[RS6000] PC-relative TLS support
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobcbfe38bef9477151222878744ef808ddceeba0bd
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (FIRST_ALTIVEC_REGNO         64)
37    (LAST_ALTIVEC_REGNO          95)
38    (LR_REGNO                    96)
39    (CTR_REGNO                   97)
40    (CA_REGNO                    98)
41    (ARG_POINTER_REGNUM          99)
42    (CR0_REGNO                   100)
43    (CR1_REGNO                   101)
44    (CR2_REGNO                   102)
45    (CR3_REGNO                   103)
46    (CR4_REGNO                   104)
47    (CR5_REGNO                   105)
48    (CR6_REGNO                   106)
49    (CR7_REGNO                   107)
50    (MAX_CR_REGNO                107)
51    (VRSAVE_REGNO                108)
52    (VSCR_REGNO                  109)
53    (FRAME_POINTER_REGNUM        110)
54   ])
57 ;; UNSPEC usage
60 (define_c_enum "unspec"
61   [UNSPEC_PROBE_STACK           ; probe stack memory reference
62    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
63    UNSPEC_TOC                   ; address of the TOC (more-or-less)
64    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
65    UNSPEC_MOVSI_GOT
66    UNSPEC_FCTIWZ
67    UNSPEC_FRIM
68    UNSPEC_FRIN
69    UNSPEC_FRIP
70    UNSPEC_FRIZ
71    UNSPEC_XSRDPI
72    UNSPEC_LD_MPIC               ; load_macho_picbase
73    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
74    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
75    UNSPEC_TLSGD
76    UNSPEC_TLSLD
77    UNSPEC_TLS_GET_ADDR
78    UNSPEC_MOVESI_FROM_CR
79    UNSPEC_MOVESI_TO_CR
80    UNSPEC_TLSDTPREL
81    UNSPEC_TLSDTPRELHA
82    UNSPEC_TLSDTPRELLO
83    UNSPEC_TLSGOTDTPREL
84    UNSPEC_TLSTPREL
85    UNSPEC_TLSTPRELHA
86    UNSPEC_TLSTPRELLO
87    UNSPEC_TLSGOTTPREL
88    UNSPEC_TLSTLS
89    UNSPEC_TLSTLS_PCREL
90    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
91    UNSPEC_STFIWX
92    UNSPEC_POPCNTB
93    UNSPEC_FRES
94    UNSPEC_SP_SET
95    UNSPEC_SP_TEST
96    UNSPEC_SYNC
97    UNSPEC_LWSYNC
98    UNSPEC_SYNC_OP
99    UNSPEC_ATOMIC
100    UNSPEC_CMPXCHG
101    UNSPEC_XCHG
102    UNSPEC_AND
103    UNSPEC_DLMZB
104    UNSPEC_DLMZB_CR
105    UNSPEC_DLMZB_STRLEN
106    UNSPEC_RSQRT
107    UNSPEC_TOCREL
108    UNSPEC_MACHOPIC_OFFSET
109    UNSPEC_BPERM
110    UNSPEC_COPYSIGN
111    UNSPEC_PARITY
112    UNSPEC_CMPB
113    UNSPEC_FCTIW
114    UNSPEC_FCTID
115    UNSPEC_LFIWAX
116    UNSPEC_LFIWZX
117    UNSPEC_FCTIWUZ
118    UNSPEC_NOP
119    UNSPEC_GRP_END_NOP
120    UNSPEC_P8V_FMRGOW
121    UNSPEC_P8V_MTVSRWZ
122    UNSPEC_P8V_RELOAD_FROM_GPR
123    UNSPEC_P8V_MTVSRD
124    UNSPEC_P8V_XXPERMDI
125    UNSPEC_P8V_RELOAD_FROM_VSX
126    UNSPEC_ADDG6S
127    UNSPEC_CDTBCD
128    UNSPEC_CBCDTD
129    UNSPEC_DIVE
130    UNSPEC_DIVEU
131    UNSPEC_UNPACK_128BIT
132    UNSPEC_PACK_128BIT
133    UNSPEC_LSQ
134    UNSPEC_FUSION_GPR
135    UNSPEC_STACK_CHECK
136    UNSPEC_CMPRB
137    UNSPEC_CMPRB2
138    UNSPEC_CMPEQB
139    UNSPEC_ADD_ROUND_TO_ODD
140    UNSPEC_SUB_ROUND_TO_ODD
141    UNSPEC_MUL_ROUND_TO_ODD
142    UNSPEC_DIV_ROUND_TO_ODD
143    UNSPEC_FMA_ROUND_TO_ODD
144    UNSPEC_SQRT_ROUND_TO_ODD
145    UNSPEC_TRUNC_ROUND_TO_ODD
146    UNSPEC_SIGNBIT
147    UNSPEC_SF_FROM_SI
148    UNSPEC_SI_FROM_SF
149    UNSPEC_PLTSEQ
150    UNSPEC_PLT16_HA
151    UNSPEC_PLT16_LO
152    UNSPEC_PLT_PCREL
153   ])
156 ;; UNSPEC_VOLATILE usage
159 (define_c_enum "unspecv"
160   [UNSPECV_BLOCK
161    UNSPECV_LL                   ; load-locked
162    UNSPECV_SC                   ; store-conditional
163    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
164    UNSPECV_EH_RR                ; eh_reg_restore
165    UNSPECV_ISYNC                ; isync instruction
166    UNSPECV_MFTB                 ; move from time base
167    UNSPECV_DARN                 ; darn 1 (deliver a random number)
168    UNSPECV_DARN_32              ; darn 2
169    UNSPECV_DARN_RAW             ; darn 0
170    UNSPECV_NLGR                 ; non-local goto receiver
171    UNSPECV_MFFS                 ; Move from FPSCR
172    UNSPECV_MFFSL                ; Move from FPSCR light instruction version
173    UNSPECV_MFFSCRN              ; Move from FPSCR float rounding mode
174    UNSPECV_MFFSCDRN             ; Move from FPSCR decimal float rounding mode
175    UNSPECV_MTFSF                ; Move to FPSCR Fields 8 to 15
176    UNSPECV_MTFSF_HI             ; Move to FPSCR Fields 0 to 7
177    UNSPECV_MTFSB0               ; Set FPSCR Field bit to 0
178    UNSPECV_MTFSB1               ; Set FPSCR Field bit to 1
179    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
180    UNSPECV_SPEC_BARRIER         ; Speculation barrier
181   ])
183 ; The three different kinds of epilogue.
184 (define_enum "epilogue_type" [normal sibcall eh_return])
186 ;; Define an insn type attribute.  This is used in function unit delay
187 ;; computations.
188 (define_attr "type"
189   "integer,two,three,
190    add,logical,shift,insert,
191    mul,halfmul,div,
192    exts,cntlz,popcnt,isel,
193    load,store,fpload,fpstore,vecload,vecstore,
194    cmp,
195    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
196    cr_logical,mfcr,mfcrf,mtcr,
197    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
198    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
199    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
200    veclogical,veccmpfx,vecexts,vecmove,
201    htm,htmsimple,dfp"
202   (const_string "integer"))
204 ;; What data size does this instruction work on?
205 ;; This is used for insert, mul and others as necessary.
206 (define_attr "size" "8,16,32,64,128" (const_string "32"))
208 ;; What is the insn_cost for this insn?  The target hook can still override
209 ;; this.  For optimizing for size the "length" attribute is used instead.
210 (define_attr "cost" "" (const_int 0))
212 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
213 ;; This is used for add, logical, shift, exts, mul.
214 (define_attr "dot" "no,yes" (const_string "no"))
216 ;; Does this instruction sign-extend its result?
217 ;; This is used for load insns.
218 (define_attr "sign_extend" "no,yes" (const_string "no"))
220 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
221 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
223 ;; Does this instruction use indexed (that is, reg+reg) addressing?
224 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
225 ;; it is automatically set based on that.  If a load or store instruction
226 ;; has fewer than two operands it needs to set this attribute manually
227 ;; or the compiler will crash.
228 (define_attr "indexed" "no,yes"
229   (if_then_else (ior (match_operand 0 "indexed_address_mem")
230                      (match_operand 1 "indexed_address_mem"))
231                 (const_string "yes")
232                 (const_string "no")))
234 ;; Does this instruction use update addressing?
235 ;; This is used for load and store insns.  See the comments for "indexed".
236 (define_attr "update" "no,yes"
237   (if_then_else (ior (match_operand 0 "update_address_mem")
238                      (match_operand 1 "update_address_mem"))
239                 (const_string "yes")
240                 (const_string "no")))
242 ;; Is this instruction using operands[2] as shift amount, and can that be a
243 ;; register?
244 ;; This is used for shift insns.
245 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
247 ;; Is this instruction using a shift amount from a register?
248 ;; This is used for shift insns.
249 (define_attr "var_shift" "no,yes"
250   (if_then_else (and (eq_attr "type" "shift")
251                      (eq_attr "maybe_var_shift" "yes"))
252                 (if_then_else (match_operand 2 "gpc_reg_operand")
253                               (const_string "yes")
254                               (const_string "no"))
255                 (const_string "no")))
257 ;; Is copying of this instruction disallowed?
258 (define_attr "cannot_copy" "no,yes" (const_string "no"))
261 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
262 ;; before the instruction.  A prefixed instruction has a prefix instruction
263 ;; word that extends the immediate value of the instructions from 12-16 bits to
264 ;; 34 bits.  The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
265 ;; insns.  The default "length" attribute will also be adjusted by default to
266 ;; be 12 bytes.
267 (define_attr "prefixed" "no,yes"
268   (cond [(ior (match_test "!TARGET_PREFIXED_ADDR")
269               (match_test "!NONJUMP_INSN_P (insn)"))
270          (const_string "no")
272          (eq_attr "type" "load,fpload,vecload")
273          (if_then_else (match_test "prefixed_load_p (insn)")
274                        (const_string "yes")
275                        (const_string "no"))
277          (eq_attr "type" "store,fpstore,vecstore")
278          (if_then_else (match_test "prefixed_store_p (insn)")
279                        (const_string "yes")
280                        (const_string "no"))
282          (eq_attr "type" "integer,add")
283          (if_then_else (match_test "prefixed_paddi_p (insn)")
284                        (const_string "yes")
285                        (const_string "no"))]
287         (const_string "no")))
289 ;; Return the number of real hardware instructions in a combined insn.  If it
290 ;; is 0, just use the length / 4.
291 (define_attr "num_insns" "" (const_int 0))
293 ;; If an insn is prefixed, return the maximum number of prefixed instructions
294 ;; in the insn.  The macro ADJUST_INSN_LENGTH uses this number to adjust the
295 ;; insn length.
296 (define_attr "max_prefixed_insns" "" (const_int 1))
298 ;; Length of the instruction (in bytes).  This length does not consider the
299 ;; length for prefixed instructions.  The macro ADJUST_INSN_LENGTH will adjust
300 ;; the length if there are prefixed instructions.
302 ;; While it might be tempting to use num_insns to calculate the length, it can
303 ;; be problematical unless all insn lengths are adjusted to use num_insns
304 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
305 ;; num_insns and recurse).
306 (define_attr "length" "" (const_int 4))
308 ;; Processor type -- this attribute must exactly match the processor_type
309 ;; enumeration in rs6000-opts.h.
310 (define_attr "cpu"
311   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
312    ppc750,ppc7400,ppc7450,
313    ppc403,ppc405,ppc440,ppc476,
314    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
315    power4,power5,power6,power7,power8,power9,future,
316    rs64a,mpccore,cell,ppca2,titan"
317   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
319 ;; The ISA we implement.
320 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
321   (const_string "any"))
323 ;; Is this alternative enabled for the current CPU/ISA/etc.?
324 (define_attr "enabled" ""
325   (cond
326     [(eq_attr "isa" "any")
327      (const_int 1)
329      (and (eq_attr "isa" "p5")
330           (match_test "TARGET_POPCNTB"))
331      (const_int 1)
333      (and (eq_attr "isa" "p6")
334           (match_test "TARGET_CMPB"))
335      (const_int 1)
337      (and (eq_attr "isa" "p7")
338           (match_test "TARGET_POPCNTD"))
339      (const_int 1)
341      (and (eq_attr "isa" "p7v")
342           (match_test "TARGET_VSX"))
343      (const_int 1)
345      (and (eq_attr "isa" "p8v")
346           (match_test "TARGET_P8_VECTOR"))
347      (const_int 1)
349      (and (eq_attr "isa" "p9v")
350           (match_test "TARGET_P9_VECTOR"))
351      (const_int 1)
353      (and (eq_attr "isa" "p9kf")
354           (match_test "TARGET_FLOAT128_TYPE"))
355      (const_int 1)
357      (and (eq_attr "isa" "p9tf")
358           (match_test "FLOAT128_VECTOR_P (TFmode)"))
359      (const_int 1)
361      (and (eq_attr "isa" "fut")
362           (match_test "TARGET_FUTURE"))
363      (const_int 1)
364     ] (const_int 0)))
366 ;; If this instruction is microcoded on the CELL processor
367 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
368 (define_attr "cell_micro" "not,conditional,always"
369   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
370                           (eq_attr "dot" "yes"))
371                      (and (eq_attr "type" "load")
372                           (eq_attr "sign_extend" "yes"))
373                      (and (eq_attr "type" "shift")
374                           (eq_attr "var_shift" "yes")))
375                 (const_string "always")
376                 (const_string "not")))
378 (automata_option "ndfa")
380 (include "rs64.md")
381 (include "mpc.md")
382 (include "40x.md")
383 (include "440.md")
384 (include "476.md")
385 (include "601.md")
386 (include "603.md")
387 (include "6xx.md")
388 (include "7xx.md")
389 (include "7450.md")
390 (include "8540.md")
391 (include "e300c2c3.md")
392 (include "e500mc.md")
393 (include "e500mc64.md")
394 (include "e5500.md")
395 (include "e6500.md")
396 (include "power4.md")
397 (include "power5.md")
398 (include "power6.md")
399 (include "power7.md")
400 (include "power8.md")
401 (include "power9.md")
402 (include "future.md")
403 (include "cell.md")
404 (include "a2.md")
405 (include "titan.md")
407 (include "predicates.md")
408 (include "constraints.md")
411 ;; Mode iterators
413 ; This mode iterator allows :GPR to be used to indicate the allowable size
414 ; of whole values in GPRs.
415 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
417 ; And again, for patterns that need two (potentially) different integer modes.
418 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
420 ; Any supported integer mode.
421 (define_mode_iterator INT [QI HI SI DI TI PTI])
423 ; Any supported integer mode that fits in one register.
424 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
426 ; Integer modes supported in VSX registers with ISA 3.0 instructions
427 (define_mode_iterator INT_ISA3 [QI HI SI DI])
429 ; Everything we can extend QImode to.
430 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
432 ; Everything we can extend HImode to.
433 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
435 ; Everything we can extend SImode to.
436 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
438 ; QImode or HImode for small integer moves and small atomic ops
439 (define_mode_iterator QHI [QI HI])
441 ; QImode, HImode, SImode for fused ops only for GPR loads
442 (define_mode_iterator QHSI [QI HI SI])
444 ; HImode or SImode for sign extended fusion ops
445 (define_mode_iterator HSI [HI SI])
447 ; SImode or DImode, even if DImode doesn't fit in GPRs.
448 (define_mode_iterator SDI [SI DI])
450 ; The size of a pointer.  Also, the size of the value that a record-condition
451 ; (one with a '.') will compare; and the size used for arithmetic carries.
452 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
454 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
455 ; PTImode is GPR only)
456 (define_mode_iterator TI2 [TI PTI])
458 ; Any hardware-supported floating-point mode
459 (define_mode_iterator FP [
460   (SF "TARGET_HARD_FLOAT")
461   (DF "TARGET_HARD_FLOAT")
462   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
464   (KF "TARGET_FLOAT128_TYPE")
465   (DD "TARGET_DFP")
466   (TD "TARGET_DFP")])
468 ; Any fma capable floating-point mode.
469 (define_mode_iterator FMA_F [
470   (SF "TARGET_HARD_FLOAT")
471   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
472   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
473   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
474   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
475   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
476   ])
478 ; Floating point move iterators to combine binary and decimal moves
479 (define_mode_iterator FMOVE32 [SF SD])
480 (define_mode_iterator FMOVE64 [DF DD])
481 (define_mode_iterator FMOVE64X [DI DF DD])
482 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
483                                 (IF "FLOAT128_IBM_P (IFmode)")
484                                 (TD "TARGET_HARD_FLOAT")])
486 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
487                                     (IF "FLOAT128_2REG_P (IFmode)")
488                                     (TD "TARGET_HARD_FLOAT")])
490 ; Iterators for 128 bit types for direct move
491 (define_mode_iterator FMOVE128_GPR [TI
492                                     V16QI
493                                     V8HI
494                                     V4SI
495                                     V4SF
496                                     V2DI
497                                     V2DF
498                                     V1TI
499                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
500                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
502 ; Iterator for 128-bit VSX types for pack/unpack
503 (define_mode_iterator FMOVE128_VSX [V1TI KF])
505 ; Iterators for converting to/from TFmode
506 (define_mode_iterator IFKF [IF KF])
508 ; Constraints for moving IF/KFmode.
509 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
511 ; Whether a floating point move is ok, don't allow SD without hardware FP
512 (define_mode_attr fmove_ok [(SF "")
513                             (DF "")
514                             (SD "TARGET_HARD_FLOAT")
515                             (DD "")])
517 ; Convert REAL_VALUE to the appropriate bits
518 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
519                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
520                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
521                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
523 ; Whether 0.0 has an all-zero bit pattern
524 (define_mode_attr zero_fp [(SF "j")
525                            (DF "j")
526                            (TF "j")
527                            (IF "j")
528                            (KF "j")
529                            (SD "wn")
530                            (DD "wn")
531                            (TD "wn")])
533 ; Definitions for 64-bit VSX
534 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
536 ; Definitions for 64-bit direct move
537 (define_mode_attr f64_dm  [(DF "wa") (DD "d")])
539 ; Definitions for 64-bit use of altivec registers
540 (define_mode_attr f64_av  [(DF "v") (DD "wn")])
542 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
543 (define_mode_attr f64_p9  [(DF "v") (DD "wn")])
545 ; These modes do not fit in integer registers in 32-bit mode.
546 (define_mode_iterator DIFD [DI DF DD])
548 ; Iterator for reciprocal estimate instructions
549 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
551 ; SFmode or DFmode.
552 (define_mode_iterator SFDF [SF DF])
554 ; And again, for when we need two FP modes in a pattern.
555 (define_mode_iterator SFDF2 [SF DF])
557 ; A generic s/d attribute, for sp/dp for example.
558 (define_mode_attr sd [(SF   "s") (DF   "d")
559                       (V4SF "s") (V2DF "d")])
561 ; "s" or nothing, for fmuls/fmul for example.
562 (define_mode_attr s [(SF "s") (DF "")])
564 ; Iterator for 128-bit floating point that uses the IBM double-double format
565 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
566                               (TF "FLOAT128_IBM_P (TFmode)")])
568 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
569 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
570                                (TF "FLOAT128_IEEE_P (TFmode)")])
572 ; Iterator for 128-bit floating point
573 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
574                                 (IF "TARGET_FLOAT128_TYPE")
575                                 (TF "TARGET_LONG_DOUBLE_128")])
577 ; Iterator for signbit on 64-bit machines with direct move
578 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
579                                (TF "FLOAT128_VECTOR_P (TFmode)")])
581 ; Iterator for ISA 3.0 supported floating point types
582 (define_mode_iterator FP_ISA3 [SF DF])
584 ; SF/DF constraint for arithmetic on traditional floating point registers
585 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
587 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
588 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
589 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
590 ; format.
591 (define_mode_attr Fv            [(SF "wa") (DF "wa") (DI "wa")])
593 ; Which isa is needed for those float instructions?
594 (define_mode_attr Fisa          [(SF "p8v")  (DF "*") (DI "*")])
596 ; FRE/FRES support
597 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
599 ; Conditional returns.
600 (define_code_iterator any_return [return simple_return])
601 (define_code_attr return_pred [(return "direct_return ()")
602                                (simple_return "1")])
603 (define_code_attr return_str [(return "") (simple_return "simple_")])
605 ; Logical operators.
606 (define_code_iterator iorxor            [ior xor])
607 (define_code_iterator and_ior_xor       [and ior xor])
609 ; Signed/unsigned variants of ops.
610 (define_code_iterator any_extend        [sign_extend zero_extend])
611 (define_code_iterator any_fix           [fix unsigned_fix])
612 (define_code_iterator any_float         [float unsigned_float])
614 (define_code_attr u  [(sign_extend      "")
615                       (zero_extend      "u")
616                       (fix              "")
617                       (unsigned_fix     "u")])
619 (define_code_attr su [(sign_extend      "s")
620                       (zero_extend      "u")
621                       (fix              "s")
622                       (unsigned_fix     "u")
623                       (float            "s")
624                       (unsigned_float   "u")])
626 (define_code_attr az [(sign_extend      "a")
627                       (zero_extend      "z")
628                       (fix              "a")
629                       (unsigned_fix     "z")
630                       (float            "a")
631                       (unsigned_float   "z")])
633 (define_code_attr uns [(fix             "")
634                        (unsigned_fix    "uns")
635                        (float           "")
636                        (unsigned_float  "uns")])
638 ; Various instructions that come in SI and DI forms.
639 ; A generic w/d attribute, for things like cmpw/cmpd.
640 (define_mode_attr wd [(QI    "b")
641                       (HI    "h")
642                       (SI    "w")
643                       (DI    "d")
644                       (V16QI "b")
645                       (V8HI  "h")
646                       (V4SI  "w")
647                       (V2DI  "d")
648                       (V1TI  "q")
649                       (TI    "q")])
651 ;; How many bits in this mode?
652 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
653                                            (SF "32") (DF "64")])
655 ; DImode bits
656 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
658 ;; Bitmask for shift instructions
659 (define_mode_attr hH [(SI "h") (DI "H")])
661 ;; A mode twice the size of the given mode
662 (define_mode_attr dmode [(SI "di") (DI "ti")])
663 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
665 ;; Suffix for reload patterns
666 (define_mode_attr ptrsize [(SI "32bit")
667                            (DI "64bit")])
669 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
670                             (DI "TARGET_64BIT")])
672 (define_mode_attr mptrsize [(SI "si")
673                             (DI "di")])
675 (define_mode_attr ptrload [(SI "lwz")
676                            (DI "ld")])
678 (define_mode_attr ptrm [(SI "m")
679                         (DI "Y")])
681 (define_mode_attr rreg [(SF   "f")
682                         (DF   "wa")
683                         (TF   "f")
684                         (TD   "f")
685                         (V4SF "wa")
686                         (V2DF "wa")])
688 (define_mode_attr rreg2 [(SF   "f")
689                          (DF   "d")])
691 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
692                                  (DF "TARGET_FCFID")])
694 ;; Mode iterator for logical operations on 128-bit types
695 (define_mode_iterator BOOL_128          [TI
696                                          PTI
697                                          (V16QI "TARGET_ALTIVEC")
698                                          (V8HI  "TARGET_ALTIVEC")
699                                          (V4SI  "TARGET_ALTIVEC")
700                                          (V4SF  "TARGET_ALTIVEC")
701                                          (V2DI  "TARGET_ALTIVEC")
702                                          (V2DF  "TARGET_ALTIVEC")
703                                          (V1TI  "TARGET_ALTIVEC")])
705 ;; For the GPRs we use 3 constraints for register outputs, two that are the
706 ;; same as the output register, and a third where the output register is an
707 ;; early clobber, so we don't have to deal with register overlaps.  For the
708 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
709 ;; either.
711 ;; Mode attribute for boolean operation register constraints for output
712 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wa,v")
713                                          (PTI   "&r,r,r")
714                                          (V16QI "wa,v,&?r,?r,?r")
715                                          (V8HI  "wa,v,&?r,?r,?r")
716                                          (V4SI  "wa,v,&?r,?r,?r")
717                                          (V4SF  "wa,v,&?r,?r,?r")
718                                          (V2DI  "wa,v,&?r,?r,?r")
719                                          (V2DF  "wa,v,&?r,?r,?r")
720                                          (V1TI  "wa,v,&?r,?r,?r")])
722 ;; Mode attribute for boolean operation register constraints for operand1
723 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wa,v")
724                                          (PTI   "r,0,r")
725                                          (V16QI "wa,v,r,0,r")
726                                          (V8HI  "wa,v,r,0,r")
727                                          (V4SI  "wa,v,r,0,r")
728                                          (V4SF  "wa,v,r,0,r")
729                                          (V2DI  "wa,v,r,0,r")
730                                          (V2DF  "wa,v,r,0,r")
731                                          (V1TI  "wa,v,r,0,r")])
733 ;; Mode attribute for boolean operation register constraints for operand2
734 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wa,v")
735                                          (PTI   "r,r,0")
736                                          (V16QI "wa,v,r,r,0")
737                                          (V8HI  "wa,v,r,r,0")
738                                          (V4SI  "wa,v,r,r,0")
739                                          (V4SF  "wa,v,r,r,0")
740                                          (V2DI  "wa,v,r,r,0")
741                                          (V2DF  "wa,v,r,r,0")
742                                          (V1TI  "wa,v,r,r,0")])
744 ;; Mode attribute for boolean operation register constraints for operand1
745 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
746 ;; is used for operand1 or operand2
747 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wa,v")
748                                          (PTI   "r,0,0")
749                                          (V16QI "wa,v,r,0,0")
750                                          (V8HI  "wa,v,r,0,0")
751                                          (V4SI  "wa,v,r,0,0")
752                                          (V4SF  "wa,v,r,0,0")
753                                          (V2DI  "wa,v,r,0,0")
754                                          (V2DF  "wa,v,r,0,0")
755                                          (V1TI  "wa,v,r,0,0")])
757 ;; Reload iterator for creating the function to allocate a base register to
758 ;; supplement addressing modes.
759 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
760                               SF SD SI DF DD DI TI PTI KF IF TF])
762 ;; Iterate over smin, smax
763 (define_code_iterator fp_minmax [smin smax])
765 (define_code_attr     minmax    [(smin "min")
766                                  (smax "max")])
768 (define_code_attr     SMINMAX   [(smin "SMIN")
769                                  (smax "SMAX")])
771 ;; Iterator to optimize the following cases:
772 ;;      D-form load to FPR register & move to Altivec register
773 ;;      Move Altivec register to FPR register and store
774 (define_mode_iterator ALTIVEC_DFORM [DF
775                                      (SF "TARGET_P8_VECTOR")
776                                      (DI "TARGET_POWERPC64")])
778 (include "darwin.md")
780 ;; Start with fixed-point load and store insns.  Here we put only the more
781 ;; complex forms.  Basic data transfer is done later.
783 (define_insn "zero_extendqi<mode>2"
784   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
785         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
786   ""
787   "@
788    lbz%U1%X1 %0,%1
789    rlwinm %0,%1,0,0xff
790    lxsibzx %x0,%y1
791    vextractub %0,%1,7"
792   [(set_attr "type" "load,shift,fpload,vecperm")
793    (set_attr "isa" "*,*,p9v,p9v")])
795 (define_insn_and_split "*zero_extendqi<mode>2_dot"
796   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
797         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
798                     (const_int 0)))
799    (clobber (match_scratch:EXTQI 0 "=r,r"))]
800   ""
801   "@
802    andi. %0,%1,0xff
803    #"
804   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
805   [(set (match_dup 0)
806         (zero_extend:EXTQI (match_dup 1)))
807    (set (match_dup 2)
808         (compare:CC (match_dup 0)
809                     (const_int 0)))]
810   ""
811   [(set_attr "type" "logical")
812    (set_attr "dot" "yes")
813    (set_attr "length" "4,8")])
815 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
816   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
817         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
818                     (const_int 0)))
819    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
820         (zero_extend:EXTQI (match_dup 1)))]
821   ""
822   "@
823    andi. %0,%1,0xff
824    #"
825   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
826   [(set (match_dup 0)
827         (zero_extend:EXTQI (match_dup 1)))
828    (set (match_dup 2)
829         (compare:CC (match_dup 0)
830                     (const_int 0)))]
831   ""
832   [(set_attr "type" "logical")
833    (set_attr "dot" "yes")
834    (set_attr "length" "4,8")])
837 (define_insn "zero_extendhi<mode>2"
838   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
839         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
840   ""
841   "@
842    lhz%U1%X1 %0,%1
843    rlwinm %0,%1,0,0xffff
844    lxsihzx %x0,%y1
845    vextractuh %0,%1,6"
846   [(set_attr "type" "load,shift,fpload,vecperm")
847    (set_attr "isa" "*,*,p9v,p9v")])
849 (define_insn_and_split "*zero_extendhi<mode>2_dot"
850   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
851         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
852                     (const_int 0)))
853    (clobber (match_scratch:EXTHI 0 "=r,r"))]
854   ""
855   "@
856    andi. %0,%1,0xffff
857    #"
858   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
859   [(set (match_dup 0)
860         (zero_extend:EXTHI (match_dup 1)))
861    (set (match_dup 2)
862         (compare:CC (match_dup 0)
863                     (const_int 0)))]
864   ""
865   [(set_attr "type" "logical")
866    (set_attr "dot" "yes")
867    (set_attr "length" "4,8")])
869 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
870   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
871         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
872                     (const_int 0)))
873    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
874         (zero_extend:EXTHI (match_dup 1)))]
875   ""
876   "@
877    andi. %0,%1,0xffff
878    #"
879   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
880   [(set (match_dup 0)
881         (zero_extend:EXTHI (match_dup 1)))
882    (set (match_dup 2)
883         (compare:CC (match_dup 0)
884                     (const_int 0)))]
885   ""
886   [(set_attr "type" "logical")
887    (set_attr "dot" "yes")
888    (set_attr "length" "4,8")])
891 (define_insn "zero_extendsi<mode>2"
892   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
893         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
894   ""
895   "@
896    lwz%U1%X1 %0,%1
897    rldicl %0,%1,0,32
898    lfiwzx %0,%y1
899    lxsiwzx %x0,%y1
900    mtvsrwz %x0,%1
901    mfvsrwz %0,%x1
902    xxextractuw %x0,%x1,4"
903   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
904    (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
906 (define_insn_and_split "*zero_extendsi<mode>2_dot"
907   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
909                     (const_int 0)))
910    (clobber (match_scratch:EXTSI 0 "=r,r"))]
911   ""
912   "@
913    rldicl. %0,%1,0,32
914    #"
915   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
916   [(set (match_dup 0)
917         (zero_extend:DI (match_dup 1)))
918    (set (match_dup 2)
919         (compare:CC (match_dup 0)
920                     (const_int 0)))]
921   ""
922   [(set_attr "type" "shift")
923    (set_attr "dot" "yes")
924    (set_attr "length" "4,8")])
926 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
927   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
928         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
929                     (const_int 0)))
930    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
931         (zero_extend:EXTSI (match_dup 1)))]
932   ""
933   "@
934    rldicl. %0,%1,0,32
935    #"
936   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
937   [(set (match_dup 0)
938         (zero_extend:EXTSI (match_dup 1)))
939    (set (match_dup 2)
940         (compare:CC (match_dup 0)
941                     (const_int 0)))]
942   ""
943   [(set_attr "type" "shift")
944    (set_attr "dot" "yes")
945    (set_attr "length" "4,8")])
948 (define_insn "extendqi<mode>2"
949   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
950         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
951   ""
952   "@
953    extsb %0,%1
954    vextsb2d %0,%1"
955   [(set_attr "type" "exts,vecperm")
956    (set_attr "isa" "*,p9v")])
958 (define_insn_and_split "*extendqi<mode>2_dot"
959   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
960         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
961                     (const_int 0)))
962    (clobber (match_scratch:EXTQI 0 "=r,r"))]
963   ""
964   "@
965    extsb. %0,%1
966    #"
967   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
968   [(set (match_dup 0)
969         (sign_extend:EXTQI (match_dup 1)))
970    (set (match_dup 2)
971         (compare:CC (match_dup 0)
972                     (const_int 0)))]
973   ""
974   [(set_attr "type" "exts")
975    (set_attr "dot" "yes")
976    (set_attr "length" "4,8")])
978 (define_insn_and_split "*extendqi<mode>2_dot2"
979   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
981                     (const_int 0)))
982    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
983         (sign_extend:EXTQI (match_dup 1)))]
984   ""
985   "@
986    extsb. %0,%1
987    #"
988   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
989   [(set (match_dup 0)
990         (sign_extend:EXTQI (match_dup 1)))
991    (set (match_dup 2)
992         (compare:CC (match_dup 0)
993                     (const_int 0)))]
994   ""
995   [(set_attr "type" "exts")
996    (set_attr "dot" "yes")
997    (set_attr "length" "4,8")])
1000 (define_expand "extendhi<mode>2"
1001   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1002         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1003   ""
1004   "")
1006 (define_insn "*extendhi<mode>2"
1007   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1008         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1009   ""
1010   "@
1011    lha%U1%X1 %0,%1
1012    extsh %0,%1
1013    #
1014    vextsh2d %0,%1"
1015   [(set_attr "type" "load,exts,fpload,vecperm")
1016    (set_attr "sign_extend" "yes")
1017    (set_attr "length" "*,*,8,*")
1018    (set_attr "isa" "*,*,p9v,p9v")])
1020 (define_split
1021   [(set (match_operand:EXTHI 0 "altivec_register_operand")
1022         (sign_extend:EXTHI
1023          (match_operand:HI 1 "indexed_or_indirect_operand")))]
1024   "TARGET_P9_VECTOR && reload_completed"
1025   [(set (match_dup 2)
1026         (match_dup 1))
1027    (set (match_dup 0)
1028         (sign_extend:EXTHI (match_dup 2)))]
1030   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1033 (define_insn_and_split "*extendhi<mode>2_dot"
1034   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1035         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1036                     (const_int 0)))
1037    (clobber (match_scratch:EXTHI 0 "=r,r"))]
1038   ""
1039   "@
1040    extsh. %0,%1
1041    #"
1042   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1043   [(set (match_dup 0)
1044         (sign_extend:EXTHI (match_dup 1)))
1045    (set (match_dup 2)
1046         (compare:CC (match_dup 0)
1047                     (const_int 0)))]
1048   ""
1049   [(set_attr "type" "exts")
1050    (set_attr "dot" "yes")
1051    (set_attr "length" "4,8")])
1053 (define_insn_and_split "*extendhi<mode>2_dot2"
1054   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1055         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1056                     (const_int 0)))
1057    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1058         (sign_extend:EXTHI (match_dup 1)))]
1059   ""
1060   "@
1061    extsh. %0,%1
1062    #"
1063   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1064   [(set (match_dup 0)
1065         (sign_extend:EXTHI (match_dup 1)))
1066    (set (match_dup 2)
1067         (compare:CC (match_dup 0)
1068                     (const_int 0)))]
1069   ""
1070   [(set_attr "type" "exts")
1071    (set_attr "dot" "yes")
1072    (set_attr "length" "4,8")])
1075 (define_insn "extendsi<mode>2"
1076   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1077                      "=r, r,   d,     wa,    wa,    v,      v,     wr")
1078         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1079                      "YZ, r,   Z,     Z,     r,     v,      v,     ?wa")))]
1080   ""
1081   "@
1082    lwa%U1%X1 %0,%1
1083    extsw %0,%1
1084    lfiwax %0,%y1
1085    lxsiwax %x0,%y1
1086    mtvsrwa %x0,%1
1087    vextsw2d %0,%1
1088    #
1089    #"
1090   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1091    (set_attr "sign_extend" "yes")
1092    (set_attr "length" "*,*,*,*,*,*,8,8")
1093    (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1095 (define_split
1096   [(set (match_operand:EXTSI 0 "int_reg_operand")
1097         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1098   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1099   [(set (match_dup 2)
1100         (match_dup 1))
1101    (set (match_dup 0)
1102         (sign_extend:DI (match_dup 2)))]
1104   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1107 (define_split
1108   [(set (match_operand:DI 0 "altivec_register_operand")
1109         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1110   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1111   [(const_int 0)]
1113   rtx dest = operands[0];
1114   rtx src = operands[1];
1115   int dest_regno = REGNO (dest);
1116   int src_regno = REGNO (src);
1117   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1118   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1120   if (BYTES_BIG_ENDIAN)
1121     {
1122       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1123       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1124     }
1125   else
1126     {
1127       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1128       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1129     }
1130   DONE;
1133 (define_insn_and_split "*extendsi<mode>2_dot"
1134   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1135         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1136                     (const_int 0)))
1137    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1138   ""
1139   "@
1140    extsw. %0,%1
1141    #"
1142   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1143   [(set (match_dup 0)
1144         (sign_extend:EXTSI (match_dup 1)))
1145    (set (match_dup 2)
1146         (compare:CC (match_dup 0)
1147                     (const_int 0)))]
1148   ""
1149   [(set_attr "type" "exts")
1150    (set_attr "dot" "yes")
1151    (set_attr "length" "4,8")])
1153 (define_insn_and_split "*extendsi<mode>2_dot2"
1154   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1155         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1156                     (const_int 0)))
1157    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1158         (sign_extend:EXTSI (match_dup 1)))]
1159   ""
1160   "@
1161    extsw. %0,%1
1162    #"
1163   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1164   [(set (match_dup 0)
1165         (sign_extend:EXTSI (match_dup 1)))
1166    (set (match_dup 2)
1167         (compare:CC (match_dup 0)
1168                     (const_int 0)))]
1169   ""
1170   [(set_attr "type" "exts")
1171    (set_attr "dot" "yes")
1172    (set_attr "length" "4,8")])
1174 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1176 (define_insn "*macchwc"
1177   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1178         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1179                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1180                                        (const_int 16))
1181                                       (sign_extend:SI
1182                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1183                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1184                     (const_int 0)))
1185    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186         (plus:SI (mult:SI (ashiftrt:SI
1187                            (match_dup 2)
1188                            (const_int 16))
1189                           (sign_extend:SI
1190                            (match_dup 1)))
1191                  (match_dup 4)))]
1192   "TARGET_MULHW"
1193   "macchw. %0,%1,%2"
1194   [(set_attr "type" "halfmul")])
1196 (define_insn "*macchw"
1197   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1198         (plus:SI (mult:SI (ashiftrt:SI
1199                            (match_operand:SI 2 "gpc_reg_operand" "r")
1200                            (const_int 16))
1201                           (sign_extend:SI
1202                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1203                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1204   "TARGET_MULHW"
1205   "macchw %0,%1,%2"
1206   [(set_attr "type" "halfmul")])
1208 (define_insn "*macchwuc"
1209   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1210         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1211                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1212                                        (const_int 16))
1213                                       (zero_extend:SI
1214                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1215                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1216                     (const_int 0)))
1217    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1218         (plus:SI (mult:SI (lshiftrt:SI
1219                            (match_dup 2)
1220                            (const_int 16))
1221                           (zero_extend:SI
1222                            (match_dup 1)))
1223                  (match_dup 4)))]
1224   "TARGET_MULHW"
1225   "macchwu. %0,%1,%2"
1226   [(set_attr "type" "halfmul")])
1228 (define_insn "*macchwu"
1229   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1230         (plus:SI (mult:SI (lshiftrt:SI
1231                            (match_operand:SI 2 "gpc_reg_operand" "r")
1232                            (const_int 16))
1233                           (zero_extend:SI
1234                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1235                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1236   "TARGET_MULHW"
1237   "macchwu %0,%1,%2"
1238   [(set_attr "type" "halfmul")])
1240 (define_insn "*machhwc"
1241   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1242         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1243                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1244                                        (const_int 16))
1245                                       (ashiftrt:SI
1246                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1247                                        (const_int 16)))
1248                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1249                     (const_int 0)))
1250    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251         (plus:SI (mult:SI (ashiftrt:SI
1252                            (match_dup 1)
1253                            (const_int 16))
1254                           (ashiftrt:SI
1255                            (match_dup 2)
1256                            (const_int 16)))
1257                  (match_dup 4)))]
1258   "TARGET_MULHW"
1259   "machhw. %0,%1,%2"
1260   [(set_attr "type" "halfmul")])
1262 (define_insn "*machhw"
1263   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264         (plus:SI (mult:SI (ashiftrt:SI
1265                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1266                            (const_int 16))
1267                           (ashiftrt:SI
1268                            (match_operand:SI 2 "gpc_reg_operand" "r")
1269                            (const_int 16)))
1270                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1271   "TARGET_MULHW"
1272   "machhw %0,%1,%2"
1273   [(set_attr "type" "halfmul")])
1275 (define_insn "*machhwuc"
1276   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1277         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1278                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1279                                        (const_int 16))
1280                                       (lshiftrt:SI
1281                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1282                                        (const_int 16)))
1283                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1284                     (const_int 0)))
1285    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1286         (plus:SI (mult:SI (lshiftrt:SI
1287                            (match_dup 1)
1288                            (const_int 16))
1289                           (lshiftrt:SI
1290                            (match_dup 2)
1291                            (const_int 16)))
1292                  (match_dup 4)))]
1293   "TARGET_MULHW"
1294   "machhwu. %0,%1,%2"
1295   [(set_attr "type" "halfmul")])
1297 (define_insn "*machhwu"
1298   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299         (plus:SI (mult:SI (lshiftrt:SI
1300                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1301                            (const_int 16))
1302                           (lshiftrt:SI
1303                            (match_operand:SI 2 "gpc_reg_operand" "r")
1304                            (const_int 16)))
1305                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1306   "TARGET_MULHW"
1307   "machhwu %0,%1,%2"
1308   [(set_attr "type" "halfmul")])
1310 (define_insn "*maclhwc"
1311   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1313                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1314                                       (sign_extend:SI
1315                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1316                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1317                     (const_int 0)))
1318    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1319         (plus:SI (mult:SI (sign_extend:SI
1320                            (match_dup 1))
1321                           (sign_extend:SI
1322                            (match_dup 2)))
1323                  (match_dup 4)))]
1324   "TARGET_MULHW"
1325   "maclhw. %0,%1,%2"
1326   [(set_attr "type" "halfmul")])
1328 (define_insn "*maclhw"
1329   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330         (plus:SI (mult:SI (sign_extend:SI
1331                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1332                           (sign_extend:SI
1333                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1334                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1335   "TARGET_MULHW"
1336   "maclhw %0,%1,%2"
1337   [(set_attr "type" "halfmul")])
1339 (define_insn "*maclhwuc"
1340   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1341         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1342                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1343                                       (zero_extend:SI
1344                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1345                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1346                     (const_int 0)))
1347    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1348         (plus:SI (mult:SI (zero_extend:SI
1349                            (match_dup 1))
1350                           (zero_extend:SI
1351                            (match_dup 2)))
1352                  (match_dup 4)))]
1353   "TARGET_MULHW"
1354   "maclhwu. %0,%1,%2"
1355   [(set_attr "type" "halfmul")])
1357 (define_insn "*maclhwu"
1358   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359         (plus:SI (mult:SI (zero_extend:SI
1360                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1361                           (zero_extend:SI
1362                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1363                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1364   "TARGET_MULHW"
1365   "maclhwu %0,%1,%2"
1366   [(set_attr "type" "halfmul")])
1368 (define_insn "*nmacchwc"
1369   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1370         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1371                               (mult:SI (ashiftrt:SI
1372                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1373                                         (const_int 16))
1374                                        (sign_extend:SI
1375                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1376                     (const_int 0)))
1377    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1378         (minus:SI (match_dup 4)
1379                   (mult:SI (ashiftrt:SI
1380                             (match_dup 2)
1381                             (const_int 16))
1382                            (sign_extend:SI
1383                             (match_dup 1)))))]
1384   "TARGET_MULHW"
1385   "nmacchw. %0,%1,%2"
1386   [(set_attr "type" "halfmul")])
1388 (define_insn "*nmacchw"
1389   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1391                   (mult:SI (ashiftrt:SI
1392                             (match_operand:SI 2 "gpc_reg_operand" "r")
1393                             (const_int 16))
1394                            (sign_extend:SI
1395                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1396   "TARGET_MULHW"
1397   "nmacchw %0,%1,%2"
1398   [(set_attr "type" "halfmul")])
1400 (define_insn "*nmachhwc"
1401   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1402         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1403                               (mult:SI (ashiftrt:SI
1404                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1405                                         (const_int 16))
1406                                        (ashiftrt:SI
1407                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1408                                         (const_int 16))))
1409                     (const_int 0)))
1410    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411         (minus:SI (match_dup 4)
1412                   (mult:SI (ashiftrt:SI
1413                             (match_dup 1)
1414                             (const_int 16))
1415                            (ashiftrt:SI
1416                             (match_dup 2)
1417                             (const_int 16)))))]
1418   "TARGET_MULHW"
1419   "nmachhw. %0,%1,%2"
1420   [(set_attr "type" "halfmul")])
1422 (define_insn "*nmachhw"
1423   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1425                   (mult:SI (ashiftrt:SI
1426                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1427                             (const_int 16))
1428                            (ashiftrt:SI
1429                             (match_operand:SI 2 "gpc_reg_operand" "r")
1430                             (const_int 16)))))]
1431   "TARGET_MULHW"
1432   "nmachhw %0,%1,%2"
1433   [(set_attr "type" "halfmul")])
1435 (define_insn "*nmaclhwc"
1436   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1437         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1438                               (mult:SI (sign_extend:SI
1439                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1440                                        (sign_extend:SI
1441                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1442                     (const_int 0)))
1443    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444         (minus:SI (match_dup 4)
1445                   (mult:SI (sign_extend:SI
1446                             (match_dup 1))
1447                            (sign_extend:SI
1448                             (match_dup 2)))))]
1449   "TARGET_MULHW"
1450   "nmaclhw. %0,%1,%2"
1451   [(set_attr "type" "halfmul")])
1453 (define_insn "*nmaclhw"
1454   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1455         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1456                   (mult:SI (sign_extend:SI
1457                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1458                            (sign_extend:SI
1459                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1460   "TARGET_MULHW"
1461   "nmaclhw %0,%1,%2"
1462   [(set_attr "type" "halfmul")])
1464 (define_insn "*mulchwc"
1465   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1466         (compare:CC (mult:SI (ashiftrt:SI
1467                               (match_operand:SI 2 "gpc_reg_operand" "r")
1468                               (const_int 16))
1469                              (sign_extend:SI
1470                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1471                     (const_int 0)))
1472    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1473         (mult:SI (ashiftrt:SI
1474                   (match_dup 2)
1475                   (const_int 16))
1476                  (sign_extend:SI
1477                   (match_dup 1))))]
1478   "TARGET_MULHW"
1479   "mulchw. %0,%1,%2"
1480   [(set_attr "type" "halfmul")])
1482 (define_insn "*mulchw"
1483   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484         (mult:SI (ashiftrt:SI
1485                   (match_operand:SI 2 "gpc_reg_operand" "r")
1486                   (const_int 16))
1487                  (sign_extend:SI
1488                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1489   "TARGET_MULHW"
1490   "mulchw %0,%1,%2"
1491   [(set_attr "type" "halfmul")])
1493 (define_insn "*mulchwuc"
1494   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1495         (compare:CC (mult:SI (lshiftrt:SI
1496                               (match_operand:SI 2 "gpc_reg_operand" "r")
1497                               (const_int 16))
1498                              (zero_extend:SI
1499                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1500                     (const_int 0)))
1501    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1502         (mult:SI (lshiftrt:SI
1503                   (match_dup 2)
1504                   (const_int 16))
1505                  (zero_extend:SI
1506                   (match_dup 1))))]
1507   "TARGET_MULHW"
1508   "mulchwu. %0,%1,%2"
1509   [(set_attr "type" "halfmul")])
1511 (define_insn "*mulchwu"
1512   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513         (mult:SI (lshiftrt:SI
1514                   (match_operand:SI 2 "gpc_reg_operand" "r")
1515                   (const_int 16))
1516                  (zero_extend:SI
1517                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1518   "TARGET_MULHW"
1519   "mulchwu %0,%1,%2"
1520   [(set_attr "type" "halfmul")])
1522 (define_insn "*mulhhwc"
1523   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1524         (compare:CC (mult:SI (ashiftrt:SI
1525                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1526                               (const_int 16))
1527                              (ashiftrt:SI
1528                               (match_operand:SI 2 "gpc_reg_operand" "r")
1529                               (const_int 16)))
1530                     (const_int 0)))
1531    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532         (mult:SI (ashiftrt:SI
1533                   (match_dup 1)
1534                   (const_int 16))
1535                  (ashiftrt:SI
1536                   (match_dup 2)
1537                   (const_int 16))))]
1538   "TARGET_MULHW"
1539   "mulhhw. %0,%1,%2"
1540   [(set_attr "type" "halfmul")])
1542 (define_insn "*mulhhw"
1543   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544         (mult:SI (ashiftrt:SI
1545                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1546                   (const_int 16))
1547                  (ashiftrt:SI
1548                   (match_operand:SI 2 "gpc_reg_operand" "r")
1549                   (const_int 16))))]
1550   "TARGET_MULHW"
1551   "mulhhw %0,%1,%2"
1552   [(set_attr "type" "halfmul")])
1554 (define_insn "*mulhhwuc"
1555   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1556         (compare:CC (mult:SI (lshiftrt:SI
1557                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1558                               (const_int 16))
1559                              (lshiftrt:SI
1560                               (match_operand:SI 2 "gpc_reg_operand" "r")
1561                               (const_int 16)))
1562                     (const_int 0)))
1563    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1564         (mult:SI (lshiftrt:SI
1565                   (match_dup 1)
1566                   (const_int 16))
1567                  (lshiftrt:SI
1568                   (match_dup 2)
1569                   (const_int 16))))]
1570   "TARGET_MULHW"
1571   "mulhhwu. %0,%1,%2"
1572   [(set_attr "type" "halfmul")])
1574 (define_insn "*mulhhwu"
1575   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1576         (mult:SI (lshiftrt:SI
1577                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1578                   (const_int 16))
1579                  (lshiftrt:SI
1580                   (match_operand:SI 2 "gpc_reg_operand" "r")
1581                   (const_int 16))))]
1582   "TARGET_MULHW"
1583   "mulhhwu %0,%1,%2"
1584   [(set_attr "type" "halfmul")])
1586 (define_insn "*mullhwc"
1587   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1588         (compare:CC (mult:SI (sign_extend:SI
1589                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1590                              (sign_extend:SI
1591                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1592                     (const_int 0)))
1593    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1594         (mult:SI (sign_extend:SI
1595                   (match_dup 1))
1596                  (sign_extend:SI
1597                   (match_dup 2))))]
1598   "TARGET_MULHW"
1599   "mullhw. %0,%1,%2"
1600   [(set_attr "type" "halfmul")])
1602 (define_insn "*mullhw"
1603   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1604         (mult:SI (sign_extend:SI
1605                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1606                  (sign_extend:SI
1607                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1608   "TARGET_MULHW"
1609   "mullhw %0,%1,%2"
1610   [(set_attr "type" "halfmul")])
1612 (define_insn "*mullhwuc"
1613   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1614         (compare:CC (mult:SI (zero_extend:SI
1615                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1616                              (zero_extend:SI
1617                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1618                     (const_int 0)))
1619    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1620         (mult:SI (zero_extend:SI
1621                   (match_dup 1))
1622                  (zero_extend:SI
1623                   (match_dup 2))))]
1624   "TARGET_MULHW"
1625   "mullhwu. %0,%1,%2"
1626   [(set_attr "type" "halfmul")])
1628 (define_insn "*mullhwu"
1629   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1630         (mult:SI (zero_extend:SI
1631                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1632                  (zero_extend:SI
1633                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1634   "TARGET_MULHW"
1635   "mullhwu %0,%1,%2"
1636   [(set_attr "type" "halfmul")])
1638 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1639 (define_insn "dlmzb"
1640   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1641         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1642                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1643                    UNSPEC_DLMZB_CR))
1644    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1645         (unspec:SI [(match_dup 1)
1646                     (match_dup 2)]
1647                    UNSPEC_DLMZB))]
1648   "TARGET_DLMZB"
1649   "dlmzb. %0,%1,%2")
1651 (define_expand "strlensi"
1652   [(set (match_operand:SI 0 "gpc_reg_operand")
1653         (unspec:SI [(match_operand:BLK 1 "general_operand")
1654                     (match_operand:QI 2 "const_int_operand")
1655                     (match_operand 3 "const_int_operand")]
1656                    UNSPEC_DLMZB_STRLEN))
1657    (clobber (match_scratch:CC 4))]
1658   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1660   rtx result = operands[0];
1661   rtx src = operands[1];
1662   rtx search_char = operands[2];
1663   rtx align = operands[3];
1664   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1665   rtx loop_label, end_label, mem, cr0, cond;
1666   if (search_char != const0_rtx
1667       || !CONST_INT_P (align)
1668       || INTVAL (align) < 8)
1669         FAIL;
1670   word1 = gen_reg_rtx (SImode);
1671   word2 = gen_reg_rtx (SImode);
1672   scratch_dlmzb = gen_reg_rtx (SImode);
1673   scratch_string = gen_reg_rtx (Pmode);
1674   loop_label = gen_label_rtx ();
1675   end_label = gen_label_rtx ();
1676   addr = force_reg (Pmode, XEXP (src, 0));
1677   emit_move_insn (scratch_string, addr);
1678   emit_label (loop_label);
1679   mem = change_address (src, SImode, scratch_string);
1680   emit_move_insn (word1, mem);
1681   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1682   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1683   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1684   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1685   emit_jump_insn (gen_rtx_SET (pc_rtx,
1686                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1687                                                      cond,
1688                                                      gen_rtx_LABEL_REF
1689                                                        (VOIDmode,
1690                                                         end_label),
1691                                                      pc_rtx)));
1692   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1693   emit_jump_insn (gen_rtx_SET (pc_rtx,
1694                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1695   emit_barrier ();
1696   emit_label (end_label);
1697   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1698   emit_insn (gen_subsi3 (result, scratch_string, addr));
1699   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1700   DONE;
1703 ;; Fixed-point arithmetic insns.
1705 (define_expand "add<mode>3"
1706   [(set (match_operand:SDI 0 "gpc_reg_operand")
1707         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1708                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1709   ""
1711   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1712     {
1713       rtx lo0 = gen_lowpart (SImode, operands[0]);
1714       rtx lo1 = gen_lowpart (SImode, operands[1]);
1715       rtx lo2 = gen_lowpart (SImode, operands[2]);
1716       rtx hi0 = gen_highpart (SImode, operands[0]);
1717       rtx hi1 = gen_highpart (SImode, operands[1]);
1718       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1720       if (!reg_or_short_operand (lo2, SImode))
1721         lo2 = force_reg (SImode, lo2);
1722       if (!adde_operand (hi2, SImode))
1723         hi2 = force_reg (SImode, hi2);
1725       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1726       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1727       DONE;
1728     }
1730   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1731     {
1732       rtx tmp = ((!can_create_pseudo_p ()
1733                   || rtx_equal_p (operands[0], operands[1]))
1734                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1736       /* Adding a constant to r0 is not a valid insn, so use a different
1737          strategy in that case.  */
1738       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1739         {
1740           if (operands[0] == operands[1])
1741             FAIL;
1742           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1743           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1744           DONE;
1745         }
1747       HOST_WIDE_INT val = INTVAL (operands[2]);
1748       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1749       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1751       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1752         FAIL;
1754       /* The ordering here is important for the prolog expander.
1755          When space is allocated from the stack, adding 'low' first may
1756          produce a temporary deallocation (which would be bad).  */
1757       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1758       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1759       DONE;
1760     }
1763 (define_insn "*add<mode>3"
1764   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1765         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1766                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1767   ""
1768   "@
1769    add %0,%1,%2
1770    addi %0,%1,%2
1771    addis %0,%1,%v2"
1772   [(set_attr "type" "add")])
1774 (define_insn "*addsi3_high"
1775   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1776         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1777                  (high:SI (match_operand 2 "" ""))))]
1778   "TARGET_MACHO && !TARGET_64BIT"
1779   "addis %0,%1,ha16(%2)"
1780   [(set_attr "type" "add")])
1782 (define_insn_and_split "*add<mode>3_dot"
1783   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1784         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1785                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1786                     (const_int 0)))
1787    (clobber (match_scratch:GPR 0 "=r,r"))]
1788   "<MODE>mode == Pmode"
1789   "@
1790    add. %0,%1,%2
1791    #"
1792   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1793   [(set (match_dup 0)
1794         (plus:GPR (match_dup 1)
1795                  (match_dup 2)))
1796    (set (match_dup 3)
1797         (compare:CC (match_dup 0)
1798                     (const_int 0)))]
1799   ""
1800   [(set_attr "type" "add")
1801    (set_attr "dot" "yes")
1802    (set_attr "length" "4,8")])
1804 (define_insn_and_split "*add<mode>3_dot2"
1805   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1806         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1807                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1808                     (const_int 0)))
1809    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1810         (plus:GPR (match_dup 1)
1811                   (match_dup 2)))]
1812   "<MODE>mode == Pmode"
1813   "@
1814    add. %0,%1,%2
1815    #"
1816   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1817   [(set (match_dup 0)
1818         (plus:GPR (match_dup 1)
1819                   (match_dup 2)))
1820    (set (match_dup 3)
1821         (compare:CC (match_dup 0)
1822                     (const_int 0)))]
1823   ""
1824   [(set_attr "type" "add")
1825    (set_attr "dot" "yes")
1826    (set_attr "length" "4,8")])
1828 (define_insn_and_split "*add<mode>3_imm_dot"
1829   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1830         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1831                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1832                     (const_int 0)))
1833    (clobber (match_scratch:GPR 0 "=r,r"))
1834    (clobber (reg:GPR CA_REGNO))]
1835   "<MODE>mode == Pmode"
1836   "@
1837    addic. %0,%1,%2
1838    #"
1839   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1840   [(set (match_dup 0)
1841         (plus:GPR (match_dup 1)
1842                   (match_dup 2)))
1843    (set (match_dup 3)
1844         (compare:CC (match_dup 0)
1845                     (const_int 0)))]
1846   ""
1847   [(set_attr "type" "add")
1848    (set_attr "dot" "yes")
1849    (set_attr "length" "4,8")])
1851 (define_insn_and_split "*add<mode>3_imm_dot2"
1852   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1853         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1854                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1855                     (const_int 0)))
1856    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1857         (plus:GPR (match_dup 1)
1858                   (match_dup 2)))
1859    (clobber (reg:GPR CA_REGNO))]
1860   "<MODE>mode == Pmode"
1861   "@
1862    addic. %0,%1,%2
1863    #"
1864   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1865   [(set (match_dup 0)
1866         (plus:GPR (match_dup 1)
1867                   (match_dup 2)))
1868    (set (match_dup 3)
1869         (compare:CC (match_dup 0)
1870                     (const_int 0)))]
1871   ""
1872   [(set_attr "type" "add")
1873    (set_attr "dot" "yes")
1874    (set_attr "length" "4,8")])
1876 ;; Split an add that we can't do in one insn into two insns, each of which
1877 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1878 ;; add should be last in case the result gets used in an address.
1880 (define_split
1881   [(set (match_operand:GPR 0 "gpc_reg_operand")
1882         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1883                   (match_operand:GPR 2 "non_add_cint_operand")))]
1884   ""
1885   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1886    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1888   HOST_WIDE_INT val = INTVAL (operands[2]);
1889   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1890   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1892   operands[4] = GEN_INT (low);
1893   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1894     operands[3] = GEN_INT (rest);
1895   else if (can_create_pseudo_p ())
1896     {
1897       operands[3] = gen_reg_rtx (DImode);
1898       emit_move_insn (operands[3], operands[2]);
1899       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1900       DONE;
1901     }
1902   else
1903     FAIL;
1907 (define_insn "add<mode>3_carry"
1908   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1909         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1910                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1911    (set (reg:P CA_REGNO)
1912         (ltu:P (plus:P (match_dup 1)
1913                        (match_dup 2))
1914                (match_dup 1)))]
1915   ""
1916   "add%I2c %0,%1,%2"
1917   [(set_attr "type" "add")])
1919 (define_insn "*add<mode>3_imm_carry_pos"
1920   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1921         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1922                 (match_operand:P 2 "short_cint_operand" "n")))
1923    (set (reg:P CA_REGNO)
1924         (geu:P (match_dup 1)
1925                (match_operand:P 3 "const_int_operand" "n")))]
1926   "INTVAL (operands[2]) > 0
1927    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1928   "addic %0,%1,%2"
1929   [(set_attr "type" "add")])
1931 (define_insn "*add<mode>3_imm_carry_0"
1932   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1933         (match_operand:P 1 "gpc_reg_operand" "r"))
1934    (set (reg:P CA_REGNO)
1935         (const_int 0))]
1936   ""
1937   "addic %0,%1,0"
1938   [(set_attr "type" "add")])
1940 (define_insn "*add<mode>3_imm_carry_m1"
1941   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1942         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1943                 (const_int -1)))
1944    (set (reg:P CA_REGNO)
1945         (ne:P (match_dup 1)
1946               (const_int 0)))]
1947   ""
1948   "addic %0,%1,-1"
1949   [(set_attr "type" "add")])
1951 (define_insn "*add<mode>3_imm_carry_neg"
1952   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1953         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1954                 (match_operand:P 2 "short_cint_operand" "n")))
1955    (set (reg:P CA_REGNO)
1956         (gtu:P (match_dup 1)
1957                (match_operand:P 3 "const_int_operand" "n")))]
1958   "INTVAL (operands[2]) < 0
1959    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1960   "addic %0,%1,%2"
1961   [(set_attr "type" "add")])
1964 (define_expand "add<mode>3_carry_in"
1965   [(parallel [
1966      (set (match_operand:GPR 0 "gpc_reg_operand")
1967           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1968                               (match_operand:GPR 2 "adde_operand"))
1969                     (reg:GPR CA_REGNO)))
1970      (clobber (reg:GPR CA_REGNO))])]
1971   ""
1973   if (operands[2] == const0_rtx)
1974     {
1975       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1976       DONE;
1977     }
1978   if (operands[2] == constm1_rtx)
1979     {
1980       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1981       DONE;
1982     }
1985 (define_insn "*add<mode>3_carry_in_internal"
1986   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1987         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1988                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1989                   (reg:GPR CA_REGNO)))
1990    (clobber (reg:GPR CA_REGNO))]
1991   ""
1992   "adde %0,%1,%2"
1993   [(set_attr "type" "add")])
1995 (define_insn "*add<mode>3_carry_in_internal2"
1996   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1997         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1998                             (reg:GPR CA_REGNO))
1999                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2000    (clobber (reg:GPR CA_REGNO))]
2001   ""
2002   "adde %0,%1,%2"
2003   [(set_attr "type" "add")])
2005 (define_insn "add<mode>3_carry_in_0"
2006   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2007         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2008                   (reg:GPR CA_REGNO)))
2009    (clobber (reg:GPR CA_REGNO))]
2010   ""
2011   "addze %0,%1"
2012   [(set_attr "type" "add")])
2014 (define_insn "add<mode>3_carry_in_m1"
2015   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2016         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2017                             (reg:GPR CA_REGNO))
2018                   (const_int -1)))
2019    (clobber (reg:GPR CA_REGNO))]
2020   ""
2021   "addme %0,%1"
2022   [(set_attr "type" "add")])
2025 (define_expand "one_cmpl<mode>2"
2026   [(set (match_operand:SDI 0 "gpc_reg_operand")
2027         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2028   ""
2030   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2031     {
2032       rs6000_split_logical (operands, NOT, false, false, false);
2033       DONE;
2034     }
2037 (define_insn "*one_cmpl<mode>2"
2038   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2040   ""
2041   "not %0,%1")
2043 (define_insn_and_split "*one_cmpl<mode>2_dot"
2044   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2045         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2046                     (const_int 0)))
2047    (clobber (match_scratch:GPR 0 "=r,r"))]
2048   "<MODE>mode == Pmode"
2049   "@
2050    not. %0,%1
2051    #"
2052   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2053   [(set (match_dup 0)
2054         (not:GPR (match_dup 1)))
2055    (set (match_dup 2)
2056         (compare:CC (match_dup 0)
2057                     (const_int 0)))]
2058   ""
2059   [(set_attr "type" "logical")
2060    (set_attr "dot" "yes")
2061    (set_attr "length" "4,8")])
2063 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2064   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2065         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2066                     (const_int 0)))
2067    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2068         (not:GPR (match_dup 1)))]
2069   "<MODE>mode == Pmode"
2070   "@
2071    not. %0,%1
2072    #"
2073   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2074   [(set (match_dup 0)
2075         (not:GPR (match_dup 1)))
2076    (set (match_dup 2)
2077         (compare:CC (match_dup 0)
2078                     (const_int 0)))]
2079   ""
2080   [(set_attr "type" "logical")
2081    (set_attr "dot" "yes")
2082    (set_attr "length" "4,8")])
2085 (define_expand "sub<mode>3"
2086   [(set (match_operand:SDI 0 "gpc_reg_operand")
2087         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2088                    (match_operand:SDI 2 "gpc_reg_operand")))]
2089   ""
2091   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2092     {
2093       rtx lo0 = gen_lowpart (SImode, operands[0]);
2094       rtx lo1 = gen_lowpart (SImode, operands[1]);
2095       rtx lo2 = gen_lowpart (SImode, operands[2]);
2096       rtx hi0 = gen_highpart (SImode, operands[0]);
2097       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2098       rtx hi2 = gen_highpart (SImode, operands[2]);
2100       if (!reg_or_short_operand (lo1, SImode))
2101         lo1 = force_reg (SImode, lo1);
2102       if (!adde_operand (hi1, SImode))
2103         hi1 = force_reg (SImode, hi1);
2105       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2106       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2107       DONE;
2108     }
2110   if (short_cint_operand (operands[1], <MODE>mode))
2111     {
2112       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2113       DONE;
2114     }
2117 (define_insn "*subf<mode>3"
2118   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2119         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2120                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2121   ""
2122   "subf %0,%1,%2"
2123   [(set_attr "type" "add")])
2125 (define_insn_and_split "*subf<mode>3_dot"
2126   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2127         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2128                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2129                     (const_int 0)))
2130    (clobber (match_scratch:GPR 0 "=r,r"))]
2131   "<MODE>mode == Pmode"
2132   "@
2133    subf. %0,%1,%2
2134    #"
2135   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2136   [(set (match_dup 0)
2137         (minus:GPR (match_dup 2)
2138                    (match_dup 1)))
2139    (set (match_dup 3)
2140         (compare:CC (match_dup 0)
2141                     (const_int 0)))]
2142   ""
2143   [(set_attr "type" "add")
2144    (set_attr "dot" "yes")
2145    (set_attr "length" "4,8")])
2147 (define_insn_and_split "*subf<mode>3_dot2"
2148   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2149         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2150                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2151                     (const_int 0)))
2152    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2153         (minus:GPR (match_dup 2)
2154                    (match_dup 1)))]
2155   "<MODE>mode == Pmode"
2156   "@
2157    subf. %0,%1,%2
2158    #"
2159   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2160   [(set (match_dup 0)
2161         (minus:GPR (match_dup 2)
2162                    (match_dup 1)))
2163    (set (match_dup 3)
2164         (compare:CC (match_dup 0)
2165                     (const_int 0)))]
2166   ""
2167   [(set_attr "type" "add")
2168    (set_attr "dot" "yes")
2169    (set_attr "length" "4,8")])
2171 (define_insn "subf<mode>3_imm"
2172   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2173         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2174                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2175    (clobber (reg:GPR CA_REGNO))]
2176   ""
2177   "subfic %0,%1,%2"
2178   [(set_attr "type" "add")])
2180 (define_insn_and_split "subf<mode>3_carry_dot2"
2181   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2182         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2183                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2184                     (const_int 0)))
2185    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2186         (minus:P (match_dup 2)
2187                    (match_dup 1)))
2188    (set (reg:P CA_REGNO)
2189         (leu:P (match_dup 1)
2190                (match_dup 2)))]
2191   "<MODE>mode == Pmode"
2192   "@
2193    subfc. %0,%1,%2
2194    #"
2195   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2196   [(parallel [(set (match_dup 0)
2197                    (minus:P (match_dup 2)
2198                             (match_dup 1)))
2199               (set (reg:P CA_REGNO)
2200                    (leu:P (match_dup 1)
2201                           (match_dup 2)))])
2202    (set (match_dup 3)
2203         (compare:CC (match_dup 0)
2204                     (const_int 0)))]
2205   ""
2206   [(set_attr "type" "add")
2207    (set_attr "dot" "yes")
2208    (set_attr "length" "4,8")])
2210 (define_insn "subf<mode>3_carry"
2211   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2212         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2213                  (match_operand:P 1 "gpc_reg_operand" "r")))
2214    (set (reg:P CA_REGNO)
2215         (leu:P (match_dup 1)
2216                (match_dup 2)))]
2217   ""
2218   "subf%I2c %0,%1,%2"
2219   [(set_attr "type" "add")])
2221 (define_insn "*subf<mode>3_imm_carry_0"
2222   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2223         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2224    (set (reg:P CA_REGNO)
2225         (eq:P (match_dup 1)
2226               (const_int 0)))]
2227   ""
2228   "subfic %0,%1,0"
2229   [(set_attr "type" "add")])
2231 (define_insn "*subf<mode>3_imm_carry_m1"
2232   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2233         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2234    (set (reg:P CA_REGNO)
2235         (const_int 1))]
2236   ""
2237   "subfic %0,%1,-1"
2238   [(set_attr "type" "add")])
2241 (define_expand "subf<mode>3_carry_in"
2242   [(parallel [
2243      (set (match_operand:GPR 0 "gpc_reg_operand")
2244           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2245                               (reg:GPR CA_REGNO))
2246                     (match_operand:GPR 2 "adde_operand")))
2247      (clobber (reg:GPR CA_REGNO))])]
2248   ""
2250   if (operands[2] == const0_rtx)
2251     {
2252       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2253       DONE;
2254     }
2255   if (operands[2] == constm1_rtx)
2256     {
2257       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2258       DONE;
2259     }
2262 (define_insn "*subf<mode>3_carry_in_internal"
2263   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2264         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2265                             (reg:GPR CA_REGNO))
2266                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2267    (clobber (reg:GPR CA_REGNO))]
2268   ""
2269   "subfe %0,%1,%2"
2270   [(set_attr "type" "add")])
2272 (define_insn "subf<mode>3_carry_in_0"
2273   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2274         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2275                   (reg:GPR CA_REGNO)))
2276    (clobber (reg:GPR CA_REGNO))]
2277   ""
2278   "subfze %0,%1"
2279   [(set_attr "type" "add")])
2281 (define_insn "subf<mode>3_carry_in_m1"
2282   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2283         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2284                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2285                   (const_int -2)))
2286    (clobber (reg:GPR CA_REGNO))]
2287   ""
2288   "subfme %0,%1"
2289   [(set_attr "type" "add")])
2291 (define_insn "subf<mode>3_carry_in_xx"
2292   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2293         (plus:GPR (reg:GPR CA_REGNO)
2294                   (const_int -1)))
2295    (clobber (reg:GPR CA_REGNO))]
2296   ""
2297   "subfe %0,%0,%0"
2298   [(set_attr "type" "add")])
2301 (define_insn "@neg<mode>2"
2302   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2303         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2304   ""
2305   "neg %0,%1"
2306   [(set_attr "type" "add")])
2308 (define_insn_and_split "*neg<mode>2_dot"
2309   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2310         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2311                     (const_int 0)))
2312    (clobber (match_scratch:GPR 0 "=r,r"))]
2313   "<MODE>mode == Pmode"
2314   "@
2315    neg. %0,%1
2316    #"
2317   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2318   [(set (match_dup 0)
2319         (neg:GPR (match_dup 1)))
2320    (set (match_dup 2)
2321         (compare:CC (match_dup 0)
2322                     (const_int 0)))]
2323   ""
2324   [(set_attr "type" "add")
2325    (set_attr "dot" "yes")
2326    (set_attr "length" "4,8")])
2328 (define_insn_and_split "*neg<mode>2_dot2"
2329   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2330         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2331                     (const_int 0)))
2332    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2333         (neg:GPR (match_dup 1)))]
2334   "<MODE>mode == Pmode"
2335   "@
2336    neg. %0,%1
2337    #"
2338   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2339   [(set (match_dup 0)
2340         (neg:GPR (match_dup 1)))
2341    (set (match_dup 2)
2342         (compare:CC (match_dup 0)
2343                     (const_int 0)))]
2344   ""
2345   [(set_attr "type" "add")
2346    (set_attr "dot" "yes")
2347    (set_attr "length" "4,8")])
2350 (define_insn "clz<mode>2"
2351   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2353   ""
2354   "cntlz<wd> %0,%1"
2355   [(set_attr "type" "cntlz")])
2357 (define_expand "ctz<mode>2"
2358    [(set (match_operand:GPR 0 "gpc_reg_operand")
2359          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2360   ""
2362   if (TARGET_CTZ)
2363     {
2364       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2365       DONE;
2366     }
2368   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2369   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2370   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2372   if (TARGET_POPCNTD)
2373     {
2374       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2375       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2376       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2377       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2378     }
2379   else
2380     {
2381       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2382       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2383       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2384       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2385     }
2387   DONE;
2390 (define_insn "ctz<mode>2_hw"
2391   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2392         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2393   "TARGET_CTZ"
2394   "cnttz<wd> %0,%1"
2395   [(set_attr "type" "cntlz")])
2397 (define_expand "ffs<mode>2"
2398   [(set (match_operand:GPR 0 "gpc_reg_operand")
2399         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2400   ""
2402   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2403   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2404   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2405   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2406   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2407   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2408   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2409   DONE;
2413 (define_expand "popcount<mode>2"
2414   [(set (match_operand:GPR 0 "gpc_reg_operand")
2415         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2416   "TARGET_POPCNTB || TARGET_POPCNTD"
2418   rs6000_emit_popcount (operands[0], operands[1]);
2419   DONE;
2422 (define_insn "popcntb<mode>2"
2423   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2424         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2425                     UNSPEC_POPCNTB))]
2426   "TARGET_POPCNTB"
2427   "popcntb %0,%1"
2428   [(set_attr "type" "popcnt")])
2430 (define_insn "popcntd<mode>2"
2431   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2432         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2433   "TARGET_POPCNTD"
2434   "popcnt<wd> %0,%1"
2435   [(set_attr "type" "popcnt")])
2438 (define_expand "parity<mode>2"
2439   [(set (match_operand:GPR 0 "gpc_reg_operand")
2440         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2441   "TARGET_POPCNTB"
2443   rs6000_emit_parity (operands[0], operands[1]);
2444   DONE;
2447 (define_insn "parity<mode>2_cmpb"
2448   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2449         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2450   "TARGET_CMPB && TARGET_POPCNTB"
2451   "prty<wd> %0,%1"
2452   [(set_attr "type" "popcnt")])
2454 (define_insn "cmpb<mode>3"
2455   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2456         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2457                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2458   "TARGET_CMPB"
2459   "cmpb %0,%1,%2"
2460   [(set_attr "type" "cmp")])
2462 ;; Since the hardware zeros the upper part of the register, save generating the
2463 ;; AND immediate if we are converting to unsigned
2464 (define_insn "*bswap<mode>2_extenddi"
2465   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2466         (zero_extend:DI
2467          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2468   "TARGET_POWERPC64"
2469   "l<wd>brx %0,%y1"
2470   [(set_attr "type" "load")])
2472 (define_insn "*bswaphi2_extendsi"
2473   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2474         (zero_extend:SI
2475          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2476   ""
2477   "lhbrx %0,%y1"
2478   [(set_attr "type" "load")])
2480 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2481 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2482 ;; load with byte swap, which can be slower than doing it in the registers.  It
2483 ;; also prevents certain failures with the RELOAD register allocator.
2485 (define_expand "bswap<mode>2"
2486   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2487    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2488   ""
2490   rtx dest = operands[0];
2491   rtx src = operands[1];
2493   if (!REG_P (dest) && !REG_P (src))
2494     src = force_reg (<MODE>mode, src);
2496   if (MEM_P (src))
2497     {
2498       src = rs6000_force_indexed_or_indirect_mem (src);
2499       emit_insn (gen_bswap<mode>2_load (dest, src));
2500     }
2501   else if (MEM_P (dest))
2502     {
2503       dest = rs6000_force_indexed_or_indirect_mem (dest);
2504       emit_insn (gen_bswap<mode>2_store (dest, src));
2505     }
2506   else
2507     emit_insn (gen_bswap<mode>2_reg (dest, src));
2508   DONE;
2511 (define_insn "bswap<mode>2_load"
2512   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2513         (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2514   ""
2515   "l<wd>brx %0,%y1"
2516   [(set_attr "type" "load")])
2518 (define_insn "bswap<mode>2_store"
2519   [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2520         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2521   ""
2522   "st<wd>brx %1,%y0"
2523   [(set_attr "type" "store")])
2525 (define_insn_and_split "bswaphi2_reg"
2526   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2527         (bswap:HI
2528          (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2529    (clobber (match_scratch:SI 2 "=&r,X"))]
2530   ""
2531   "@
2532    #
2533    xxbrh %x0,%x1"
2534   "reload_completed && int_reg_operand (operands[0], HImode)"
2535   [(set (match_dup 3)
2536         (and:SI (lshiftrt:SI (match_dup 4)
2537                              (const_int 8))
2538                 (const_int 255)))
2539    (set (match_dup 2)
2540         (and:SI (ashift:SI (match_dup 4)
2541                            (const_int 8))
2542                 (const_int 65280)))             ;; 0xff00
2543    (set (match_dup 3)
2544         (ior:SI (match_dup 3)
2545                 (match_dup 2)))]
2547   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2548   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2550   [(set_attr "length" "12,4")
2551    (set_attr "type" "*,vecperm")
2552    (set_attr "isa" "*,p9v")])
2554 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2555 ;; zero_extract insns do not change for -mlittle.
2556 (define_insn_and_split "bswapsi2_reg"
2557   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2558         (bswap:SI
2559          (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2560   ""
2561   "@
2562    #
2563    xxbrw %x0,%x1"
2564   "reload_completed && int_reg_operand (operands[0], SImode)"
2565   [(set (match_dup 0)                                   ; DABC
2566         (rotate:SI (match_dup 1)
2567                    (const_int 24)))
2568    (set (match_dup 0)                                   ; DCBC
2569         (ior:SI (and:SI (ashift:SI (match_dup 1)
2570                                    (const_int 8))
2571                         (const_int 16711680))
2572                 (and:SI (match_dup 0)
2573                         (const_int -16711681))))
2574    (set (match_dup 0)                                   ; DCBA
2575         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2576                                      (const_int 24))
2577                         (const_int 255))
2578                 (and:SI (match_dup 0)
2579                         (const_int -256))))]
2580   ""
2581   [(set_attr "length" "12,4")
2582    (set_attr "type" "*,vecperm")
2583    (set_attr "isa" "*,p9v")])
2585 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2586 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2587 ;; complex code.
2589 (define_expand "bswapdi2"
2590   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2591                    (bswap:DI
2592                     (match_operand:DI 1 "reg_or_mem_operand")))
2593               (clobber (match_scratch:DI 2))
2594               (clobber (match_scratch:DI 3))])]
2595   ""
2597   rtx dest = operands[0];
2598   rtx src = operands[1];
2600   if (!REG_P (dest) && !REG_P (src))
2601     operands[1] = src = force_reg (DImode, src);
2603   if (TARGET_POWERPC64 && TARGET_LDBRX)
2604     {
2605       if (MEM_P (src))
2606         {
2607           src = rs6000_force_indexed_or_indirect_mem (src);
2608           emit_insn (gen_bswapdi2_load (dest, src));
2609         }
2610       else if (MEM_P (dest))
2611         {
2612           dest = rs6000_force_indexed_or_indirect_mem (dest);
2613           emit_insn (gen_bswapdi2_store (dest, src));
2614         }
2615       else if (TARGET_P9_VECTOR)
2616         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2617       else
2618         emit_insn (gen_bswapdi2_reg (dest, src));
2619       DONE;
2620     }
2622   if (!TARGET_POWERPC64)
2623     {
2624       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2625          that uses 64-bit registers needs the same scratch registers as 64-bit
2626          mode.  */
2627       emit_insn (gen_bswapdi2_32bit (dest, src));
2628       DONE;
2629     }
2632 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2633 (define_insn "bswapdi2_load"
2634   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2635         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2636   "TARGET_POWERPC64 && TARGET_LDBRX"
2637   "ldbrx %0,%y1"
2638   [(set_attr "type" "load")])
2640 (define_insn "bswapdi2_store"
2641   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2642         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2643   "TARGET_POWERPC64 && TARGET_LDBRX"
2644   "stdbrx %1,%y0"
2645   [(set_attr "type" "store")])
2647 (define_insn "bswapdi2_xxbrd"
2648   [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2649         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2650   "TARGET_P9_VECTOR"
2651   "xxbrd %x0,%x1"
2652   [(set_attr "type" "vecperm")
2653    (set_attr "isa" "p9v")])
2655 (define_insn "bswapdi2_reg"
2656   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2657         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2658    (clobber (match_scratch:DI 2 "=&r"))
2659    (clobber (match_scratch:DI 3 "=&r"))]
2660   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2661   "#"
2662   [(set_attr "length" "36")])
2664 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2665 (define_insn "*bswapdi2_64bit"
2666   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2667         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2668    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2669    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2670   "TARGET_POWERPC64 && !TARGET_LDBRX
2671    && (REG_P (operands[0]) || REG_P (operands[1]))
2672    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2673    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2674   "#"
2675   [(set_attr "length" "16,12,36")])
2677 (define_split
2678   [(set (match_operand:DI 0 "gpc_reg_operand")
2679         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2680    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2681    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2682   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2683   [(const_int 0)]
2685   rtx dest   = operands[0];
2686   rtx src    = operands[1];
2687   rtx op2    = operands[2];
2688   rtx op3    = operands[3];
2689   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2690                                     BYTES_BIG_ENDIAN ? 4 : 0);
2691   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2692                                      BYTES_BIG_ENDIAN ? 4 : 0);
2693   rtx addr1;
2694   rtx addr2;
2695   rtx word1;
2696   rtx word2;
2698   addr1 = XEXP (src, 0);
2699   if (GET_CODE (addr1) == PLUS)
2700     {
2701       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2702       if (TARGET_AVOID_XFORM)
2703         {
2704           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2705           addr2 = op2;
2706         }
2707       else
2708         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2709     }
2710   else if (TARGET_AVOID_XFORM)
2711     {
2712       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2713       addr2 = op2;
2714     }
2715   else
2716     {
2717       emit_move_insn (op2, GEN_INT (4));
2718       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2719     }
2721   word1 = change_address (src, SImode, addr1);
2722   word2 = change_address (src, SImode, addr2);
2724   if (BYTES_BIG_ENDIAN)
2725     {
2726       emit_insn (gen_bswapsi2 (op3_32, word2));
2727       emit_insn (gen_bswapsi2 (dest_32, word1));
2728     }
2729   else
2730     {
2731       emit_insn (gen_bswapsi2 (op3_32, word1));
2732       emit_insn (gen_bswapsi2 (dest_32, word2));
2733     }
2735   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2736   emit_insn (gen_iordi3 (dest, dest, op3));
2737   DONE;
2740 (define_split
2741   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2742         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2743    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2744    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2745   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2746   [(const_int 0)]
2748   rtx dest   = operands[0];
2749   rtx src    = operands[1];
2750   rtx op2    = operands[2];
2751   rtx op3    = operands[3];
2752   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2753                                     BYTES_BIG_ENDIAN ? 4 : 0);
2754   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2755                                     BYTES_BIG_ENDIAN ? 4 : 0);
2756   rtx addr1;
2757   rtx addr2;
2758   rtx word1;
2759   rtx word2;
2761   addr1 = XEXP (dest, 0);
2762   if (GET_CODE (addr1) == PLUS)
2763     {
2764       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2765       if (TARGET_AVOID_XFORM)
2766         {
2767           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2768           addr2 = op2;
2769         }
2770       else
2771         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2772     }
2773   else if (TARGET_AVOID_XFORM)
2774     {
2775       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2776       addr2 = op2;
2777     }
2778   else
2779     {
2780       emit_move_insn (op2, GEN_INT (4));
2781       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2782     }
2784   word1 = change_address (dest, SImode, addr1);
2785   word2 = change_address (dest, SImode, addr2);
2787   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2789   if (BYTES_BIG_ENDIAN)
2790     {
2791       emit_insn (gen_bswapsi2 (word1, src_si));
2792       emit_insn (gen_bswapsi2 (word2, op3_si));
2793     }
2794   else
2795     {
2796       emit_insn (gen_bswapsi2 (word2, src_si));
2797       emit_insn (gen_bswapsi2 (word1, op3_si));
2798     }
2799   DONE;
2802 (define_split
2803   [(set (match_operand:DI 0 "gpc_reg_operand")
2804         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2805    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2806    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2807   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2808   [(const_int 0)]
2810   rtx dest    = operands[0];
2811   rtx src     = operands[1];
2812   rtx op2     = operands[2];
2813   rtx op3     = operands[3];
2814   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2815   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2816   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2817   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2818   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2820   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2821   emit_insn (gen_bswapsi2 (dest_si, src_si));
2822   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2823   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2824   emit_insn (gen_iordi3 (dest, dest, op3));
2825   DONE;
2828 (define_insn "bswapdi2_32bit"
2829   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2830         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2831    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2832   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2833   "#"
2834   [(set_attr "length" "16,12,36")])
2836 (define_split
2837   [(set (match_operand:DI 0 "gpc_reg_operand")
2838         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2839    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2840   "!TARGET_POWERPC64 && reload_completed"
2841   [(const_int 0)]
2843   rtx dest  = operands[0];
2844   rtx src   = operands[1];
2845   rtx op2   = operands[2];
2846   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2847   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2848   rtx addr1;
2849   rtx addr2;
2850   rtx word1;
2851   rtx word2;
2853   addr1 = XEXP (src, 0);
2854   if (GET_CODE (addr1) == PLUS)
2855     {
2856       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2857       if (TARGET_AVOID_XFORM
2858           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2859         {
2860           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2861           addr2 = op2;
2862         }
2863       else
2864         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2865     }
2866   else if (TARGET_AVOID_XFORM
2867            || REGNO (addr1) == REGNO (dest2))
2868     {
2869       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2870       addr2 = op2;
2871     }
2872   else
2873     {
2874       emit_move_insn (op2, GEN_INT (4));
2875       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2876     }
2878   word1 = change_address (src, SImode, addr1);
2879   word2 = change_address (src, SImode, addr2);
2881   emit_insn (gen_bswapsi2 (dest2, word1));
2882   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2883      thus allowing us to omit an early clobber on the output.  */
2884   emit_insn (gen_bswapsi2 (dest1, word2));
2885   DONE;
2888 (define_split
2889   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2890         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2891    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2892   "!TARGET_POWERPC64 && reload_completed"
2893   [(const_int 0)]
2895   rtx dest = operands[0];
2896   rtx src  = operands[1];
2897   rtx op2  = operands[2];
2898   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2899   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2900   rtx addr1;
2901   rtx addr2;
2902   rtx word1;
2903   rtx word2;
2905   addr1 = XEXP (dest, 0);
2906   if (GET_CODE (addr1) == PLUS)
2907     {
2908       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2909       if (TARGET_AVOID_XFORM)
2910         {
2911           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2912           addr2 = op2;
2913         }
2914       else
2915         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2916     }
2917   else if (TARGET_AVOID_XFORM)
2918     {
2919       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2920       addr2 = op2;
2921     }
2922   else
2923     {
2924       emit_move_insn (op2, GEN_INT (4));
2925       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2926     }
2928   word1 = change_address (dest, SImode, addr1);
2929   word2 = change_address (dest, SImode, addr2);
2931   emit_insn (gen_bswapsi2 (word2, src1));
2932   emit_insn (gen_bswapsi2 (word1, src2));
2933   DONE;
2936 (define_split
2937   [(set (match_operand:DI 0 "gpc_reg_operand")
2938         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2939    (clobber (match_operand:SI 2 ""))]
2940   "!TARGET_POWERPC64 && reload_completed"
2941   [(const_int 0)]
2943   rtx dest  = operands[0];
2944   rtx src   = operands[1];
2945   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2946   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2947   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2948   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2950   emit_insn (gen_bswapsi2 (dest1, src2));
2951   emit_insn (gen_bswapsi2 (dest2, src1));
2952   DONE;
2956 (define_insn "mul<mode>3"
2957   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2958         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2959                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2960   ""
2961   "@
2962    mull<wd> %0,%1,%2
2963    mulli %0,%1,%2"
2964    [(set_attr "type" "mul")
2965     (set (attr "size")
2966       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2967                 (const_string "8")
2968              (match_operand:GPR 2 "short_cint_operand")
2969                 (const_string "16")]
2970         (const_string "<bits>")))])
2972 (define_insn_and_split "*mul<mode>3_dot"
2973   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2974         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2975                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2976                     (const_int 0)))
2977    (clobber (match_scratch:GPR 0 "=r,r"))]
2978   "<MODE>mode == Pmode"
2979   "@
2980    mull<wd>. %0,%1,%2
2981    #"
2982   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2983   [(set (match_dup 0)
2984         (mult:GPR (match_dup 1)
2985                   (match_dup 2)))
2986    (set (match_dup 3)
2987         (compare:CC (match_dup 0)
2988                     (const_int 0)))]
2989   ""
2990   [(set_attr "type" "mul")
2991    (set_attr "size" "<bits>")
2992    (set_attr "dot" "yes")
2993    (set_attr "length" "4,8")])
2995 (define_insn_and_split "*mul<mode>3_dot2"
2996   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2997         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2998                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2999                     (const_int 0)))
3000    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3001         (mult:GPR (match_dup 1)
3002                   (match_dup 2)))]
3003   "<MODE>mode == Pmode"
3004   "@
3005    mull<wd>. %0,%1,%2
3006    #"
3007   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3008   [(set (match_dup 0)
3009         (mult:GPR (match_dup 1)
3010                   (match_dup 2)))
3011    (set (match_dup 3)
3012         (compare:CC (match_dup 0)
3013                     (const_int 0)))]
3014   ""
3015   [(set_attr "type" "mul")
3016    (set_attr "size" "<bits>")
3017    (set_attr "dot" "yes")
3018    (set_attr "length" "4,8")])
3021 (define_expand "<su>mul<mode>3_highpart"
3022   [(set (match_operand:GPR 0 "gpc_reg_operand")
3023         (subreg:GPR
3024           (mult:<DMODE> (any_extend:<DMODE>
3025                           (match_operand:GPR 1 "gpc_reg_operand"))
3026                         (any_extend:<DMODE>
3027                           (match_operand:GPR 2 "gpc_reg_operand")))
3028          0))]
3029   ""
3031   if (<MODE>mode == SImode && TARGET_POWERPC64)
3032     {
3033       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3034                                              operands[2]));
3035       DONE;
3036     }
3038   if (!WORDS_BIG_ENDIAN)
3039     {
3040       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3041                                                  operands[2]));
3042       DONE;
3043     }
3046 (define_insn "*<su>mul<mode>3_highpart"
3047   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3048         (subreg:GPR
3049           (mult:<DMODE> (any_extend:<DMODE>
3050                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
3051                         (any_extend:<DMODE>
3052                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
3053          0))]
3054   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3055   "mulh<wd><u> %0,%1,%2"
3056   [(set_attr "type" "mul")
3057    (set_attr "size" "<bits>")])
3059 (define_insn "<su>mulsi3_highpart_le"
3060   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3061         (subreg:SI
3062           (mult:DI (any_extend:DI
3063                      (match_operand:SI 1 "gpc_reg_operand" "r"))
3064                    (any_extend:DI
3065                      (match_operand:SI 2 "gpc_reg_operand" "r")))
3066          4))]
3067   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3068   "mulhw<u> %0,%1,%2"
3069   [(set_attr "type" "mul")])
3071 (define_insn "<su>muldi3_highpart_le"
3072   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3073         (subreg:DI
3074           (mult:TI (any_extend:TI
3075                      (match_operand:DI 1 "gpc_reg_operand" "r"))
3076                    (any_extend:TI
3077                      (match_operand:DI 2 "gpc_reg_operand" "r")))
3078          8))]
3079   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3080   "mulhd<u> %0,%1,%2"
3081   [(set_attr "type" "mul")
3082    (set_attr "size" "64")])
3084 (define_insn "<su>mulsi3_highpart_64"
3085   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3086         (truncate:SI
3087           (lshiftrt:DI
3088             (mult:DI (any_extend:DI
3089                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3090                      (any_extend:DI
3091                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3092             (const_int 32))))]
3093   "TARGET_POWERPC64"
3094   "mulhw<u> %0,%1,%2"
3095   [(set_attr "type" "mul")])
3097 (define_expand "<u>mul<mode><dmode>3"
3098   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3099         (mult:<DMODE> (any_extend:<DMODE>
3100                         (match_operand:GPR 1 "gpc_reg_operand"))
3101                       (any_extend:<DMODE>
3102                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3103   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3105   rtx l = gen_reg_rtx (<MODE>mode);
3106   rtx h = gen_reg_rtx (<MODE>mode);
3107   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3108   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3109   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3110   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3111   DONE;
3114 (define_insn "*maddld<mode>4"
3115   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3116         (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3117                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
3118                   (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3119   "TARGET_MADDLD"
3120   "maddld %0,%1,%2,%3"
3121   [(set_attr "type" "mul")])
3123 (define_insn "udiv<mode>3"
3124   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3125         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3126                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3127   ""
3128   "div<wd>u %0,%1,%2"
3129   [(set_attr "type" "div")
3130    (set_attr "size" "<bits>")])
3133 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3134 ;; modulus.  If it isn't a power of two, force operands into register and do
3135 ;; a normal divide.
3136 (define_expand "div<mode>3"
3137   [(set (match_operand:GPR 0 "gpc_reg_operand")
3138         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3139                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3140   ""
3142   if (CONST_INT_P (operands[2])
3143       && INTVAL (operands[2]) > 0
3144       && exact_log2 (INTVAL (operands[2])) >= 0)
3145     {
3146       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3147       DONE;
3148     }
3150   operands[2] = force_reg (<MODE>mode, operands[2]);
3153 (define_insn "*div<mode>3"
3154   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3155         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3156                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3157   ""
3158   "div<wd> %0,%1,%2"
3159   [(set_attr "type" "div")
3160    (set_attr "size" "<bits>")])
3162 (define_insn "div<mode>3_sra"
3163   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3164         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3165                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3166    (clobber (reg:GPR CA_REGNO))]
3167   ""
3168   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3169   [(set_attr "type" "two")
3170    (set_attr "length" "8")])
3172 (define_insn_and_split "*div<mode>3_sra_dot"
3173   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3174         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3175                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3176                     (const_int 0)))
3177    (clobber (match_scratch:GPR 0 "=r,r"))
3178    (clobber (reg:GPR CA_REGNO))]
3179   "<MODE>mode == Pmode"
3180   "@
3181    sra<wd>i %0,%1,%p2\;addze. %0,%0
3182    #"
3183   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3184   [(parallel [(set (match_dup 0)
3185                    (div:GPR (match_dup 1)
3186                             (match_dup 2)))
3187               (clobber (reg:GPR CA_REGNO))])
3188    (set (match_dup 3)
3189         (compare:CC (match_dup 0)
3190                     (const_int 0)))]
3191   ""
3192   [(set_attr "type" "two")
3193    (set_attr "length" "8,12")
3194    (set_attr "cell_micro" "not")])
3196 (define_insn_and_split "*div<mode>3_sra_dot2"
3197   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3198         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3199                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3200                     (const_int 0)))
3201    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3202         (div:GPR (match_dup 1)
3203                  (match_dup 2)))
3204    (clobber (reg:GPR CA_REGNO))]
3205   "<MODE>mode == Pmode"
3206   "@
3207    sra<wd>i %0,%1,%p2\;addze. %0,%0
3208    #"
3209   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210   [(parallel [(set (match_dup 0)
3211                    (div:GPR (match_dup 1)
3212                             (match_dup 2)))
3213               (clobber (reg:GPR CA_REGNO))])
3214    (set (match_dup 3)
3215         (compare:CC (match_dup 0)
3216                     (const_int 0)))]
3217   ""
3218   [(set_attr "type" "two")
3219    (set_attr "length" "8,12")
3220    (set_attr "cell_micro" "not")])
3222 (define_expand "mod<mode>3"
3223   [(set (match_operand:GPR 0 "gpc_reg_operand")
3224         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3225                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3226   ""
3228   int i;
3229   rtx temp1;
3230   rtx temp2;
3232   if (!CONST_INT_P (operands[2])
3233       || INTVAL (operands[2]) <= 0
3234       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3235     {
3236       if (!TARGET_MODULO)
3237         FAIL;
3239       operands[2] = force_reg (<MODE>mode, operands[2]);
3240     }
3241   else
3242     {
3243       temp1 = gen_reg_rtx (<MODE>mode);
3244       temp2 = gen_reg_rtx (<MODE>mode);
3246       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3247       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3248       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3249       DONE;
3250     }
3253 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3254 ;; mod, prefer putting the result of mod into a different register
3255 (define_insn "*mod<mode>3"
3256   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3257         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3258                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3259   "TARGET_MODULO"
3260   "mods<wd> %0,%1,%2"
3261   [(set_attr "type" "div")
3262    (set_attr "size" "<bits>")])
3265 (define_insn "umod<mode>3"
3266   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3267         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3268                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3269   "TARGET_MODULO"
3270   "modu<wd> %0,%1,%2"
3271   [(set_attr "type" "div")
3272    (set_attr "size" "<bits>")])
3274 ;; On machines with modulo support, do a combined div/mod the old fashioned
3275 ;; method, since the multiply/subtract is faster than doing the mod instruction
3276 ;; after a divide.
3278 (define_peephole2
3279   [(set (match_operand:GPR 0 "gpc_reg_operand")
3280         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3281                  (match_operand:GPR 2 "gpc_reg_operand")))
3282    (set (match_operand:GPR 3 "gpc_reg_operand")
3283         (mod:GPR (match_dup 1)
3284                  (match_dup 2)))]
3285   "TARGET_MODULO
3286    && ! reg_mentioned_p (operands[0], operands[1])
3287    && ! reg_mentioned_p (operands[0], operands[2])
3288    && ! reg_mentioned_p (operands[3], operands[1])
3289    && ! reg_mentioned_p (operands[3], operands[2])"
3290   [(set (match_dup 0)
3291         (div:GPR (match_dup 1)
3292                  (match_dup 2)))
3293    (set (match_dup 3)
3294         (mult:GPR (match_dup 0)
3295                   (match_dup 2)))
3296    (set (match_dup 3)
3297         (minus:GPR (match_dup 1)
3298                    (match_dup 3)))])
3300 (define_peephole2
3301   [(set (match_operand:GPR 0 "gpc_reg_operand")
3302         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3303                   (match_operand:GPR 2 "gpc_reg_operand")))
3304    (set (match_operand:GPR 3 "gpc_reg_operand")
3305         (umod:GPR (match_dup 1)
3306                   (match_dup 2)))]
3307   "TARGET_MODULO
3308    && ! reg_mentioned_p (operands[0], operands[1])
3309    && ! reg_mentioned_p (operands[0], operands[2])
3310    && ! reg_mentioned_p (operands[3], operands[1])
3311    && ! reg_mentioned_p (operands[3], operands[2])"
3312   [(set (match_dup 0)
3313         (udiv:GPR (match_dup 1)
3314                   (match_dup 2)))
3315    (set (match_dup 3)
3316         (mult:GPR (match_dup 0)
3317                   (match_dup 2)))
3318    (set (match_dup 3)
3319         (minus:GPR (match_dup 1)
3320                    (match_dup 3)))])
3323 ;; Logical instructions
3324 ;; The logical instructions are mostly combined by using match_operator,
3325 ;; but the plain AND insns are somewhat different because there is no
3326 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3327 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3329 (define_expand "and<mode>3"
3330   [(set (match_operand:SDI 0 "gpc_reg_operand")
3331         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3332                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3333   ""
3335   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3336     {
3337       rs6000_split_logical (operands, AND, false, false, false);
3338       DONE;
3339     }
3341   if (CONST_INT_P (operands[2]))
3342     {
3343       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3344         {
3345           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3346           DONE;
3347         }
3349       if (logical_const_operand (operands[2], <MODE>mode))
3350         {
3351           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3352           DONE;
3353         }
3355       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3356         {
3357           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3358           DONE;
3359         }
3361       operands[2] = force_reg (<MODE>mode, operands[2]);
3362     }
3366 (define_insn "and<mode>3_imm"
3367   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3368         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3369                  (match_operand:GPR 2 "logical_const_operand" "n")))
3370    (clobber (match_scratch:CC 3 "=x"))]
3371   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3372   "andi%e2. %0,%1,%u2"
3373   [(set_attr "type" "logical")
3374    (set_attr "dot" "yes")])
3376 (define_insn_and_split "*and<mode>3_imm_dot"
3377   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3378         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3379                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3380                     (const_int 0)))
3381    (clobber (match_scratch:GPR 0 "=r,r"))
3382    (clobber (match_scratch:CC 4 "=X,x"))]
3383   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3384    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3385   "@
3386    andi%e2. %0,%1,%u2
3387    #"
3388   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3389   [(parallel [(set (match_dup 0)
3390                    (and:GPR (match_dup 1)
3391                             (match_dup 2)))
3392               (clobber (match_dup 4))])
3393    (set (match_dup 3)
3394         (compare:CC (match_dup 0)
3395                     (const_int 0)))]
3396   ""
3397   [(set_attr "type" "logical")
3398    (set_attr "dot" "yes")
3399    (set_attr "length" "4,8")])
3401 (define_insn_and_split "*and<mode>3_imm_dot2"
3402   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3403         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3404                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3405                     (const_int 0)))
3406    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3407         (and:GPR (match_dup 1)
3408                  (match_dup 2)))
3409    (clobber (match_scratch:CC 4 "=X,x"))]
3410   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3411    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3412   "@
3413    andi%e2. %0,%1,%u2
3414    #"
3415   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3416   [(parallel [(set (match_dup 0)
3417                    (and:GPR (match_dup 1)
3418                             (match_dup 2)))
3419               (clobber (match_dup 4))])
3420    (set (match_dup 3)
3421         (compare:CC (match_dup 0)
3422                     (const_int 0)))]
3423   ""
3424   [(set_attr "type" "logical")
3425    (set_attr "dot" "yes")
3426    (set_attr "length" "4,8")])
3428 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3429   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3430         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3431                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3432                     (const_int 0)))
3433    (clobber (match_scratch:GPR 0 "=r,r"))]
3434   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3435    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3436   "@
3437    andi%e2. %0,%1,%u2
3438    #"
3439   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3440   [(set (match_dup 0)
3441         (and:GPR (match_dup 1)
3442                  (match_dup 2)))
3443    (set (match_dup 3)
3444         (compare:CC (match_dup 0)
3445                     (const_int 0)))]
3446   ""
3447   [(set_attr "type" "logical")
3448    (set_attr "dot" "yes")
3449    (set_attr "length" "4,8")])
3451 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3452   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3453         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3454                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3455                     (const_int 0)))
3456    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3457         (and:GPR (match_dup 1)
3458                  (match_dup 2)))]
3459   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3460    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3461   "@
3462    andi%e2. %0,%1,%u2
3463    #"
3464   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3465   [(set (match_dup 0)
3466         (and:GPR (match_dup 1)
3467                  (match_dup 2)))
3468    (set (match_dup 3)
3469         (compare:CC (match_dup 0)
3470                     (const_int 0)))]
3471   ""
3472   [(set_attr "type" "logical")
3473    (set_attr "dot" "yes")
3474    (set_attr "length" "4,8")])
3476 (define_insn "*and<mode>3_imm_dot_shifted"
3477   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3478         (compare:CC
3479           (and:GPR
3480             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3481                           (match_operand:SI 4 "const_int_operand" "n"))
3482             (match_operand:GPR 2 "const_int_operand" "n"))
3483           (const_int 0)))
3484    (clobber (match_scratch:GPR 0 "=r"))]
3485   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3486                                    << INTVAL (operands[4])),
3487                           DImode)
3488    && (<MODE>mode == Pmode
3489        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3491   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3492   return "andi%e2. %0,%1,%u2";
3494   [(set_attr "type" "logical")
3495    (set_attr "dot" "yes")])
3498 (define_insn "and<mode>3_mask"
3499   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3500         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3501                  (match_operand:GPR 2 "const_int_operand" "n")))]
3502   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3504   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3506   [(set_attr "type" "shift")])
3508 (define_insn_and_split "*and<mode>3_mask_dot"
3509   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3510         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3511                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3512                     (const_int 0)))
3513    (clobber (match_scratch:GPR 0 "=r,r"))]
3514   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515    && !logical_const_operand (operands[2], <MODE>mode)
3516    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3518   if (which_alternative == 0)
3519     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3520   else
3521     return "#";
3523   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3524   [(set (match_dup 0)
3525         (and:GPR (match_dup 1)
3526                  (match_dup 2)))
3527    (set (match_dup 3)
3528         (compare:CC (match_dup 0)
3529                     (const_int 0)))]
3530   ""
3531   [(set_attr "type" "shift")
3532    (set_attr "dot" "yes")
3533    (set_attr "length" "4,8")])
3535 (define_insn_and_split "*and<mode>3_mask_dot2"
3536   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3537         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3538                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3539                     (const_int 0)))
3540    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3541         (and:GPR (match_dup 1)
3542                  (match_dup 2)))]
3543   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3544    && !logical_const_operand (operands[2], <MODE>mode)
3545    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3547   if (which_alternative == 0)
3548     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3549   else
3550     return "#";
3552   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3553   [(set (match_dup 0)
3554         (and:GPR (match_dup 1)
3555                  (match_dup 2)))
3556    (set (match_dup 3)
3557         (compare:CC (match_dup 0)
3558                     (const_int 0)))]
3559   ""
3560   [(set_attr "type" "shift")
3561    (set_attr "dot" "yes")
3562    (set_attr "length" "4,8")])
3565 (define_insn_and_split "*and<mode>3_2insn"
3566   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3567         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3568                  (match_operand:GPR 2 "const_int_operand" "n")))]
3569   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3570    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3571         || logical_const_operand (operands[2], <MODE>mode))"
3572   "#"
3573   "&& 1"
3574   [(pc)]
3576   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3577   DONE;
3579   [(set_attr "type" "shift")
3580    (set_attr "length" "8")])
3582 (define_insn_and_split "*and<mode>3_2insn_dot"
3583   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3584         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3585                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3586                     (const_int 0)))
3587    (clobber (match_scratch:GPR 0 "=r,r"))]
3588   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3589    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3590    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3591         || logical_const_operand (operands[2], <MODE>mode))"
3592   "#"
3593   "&& reload_completed"
3594   [(pc)]
3596   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3597   DONE;
3599   [(set_attr "type" "shift")
3600    (set_attr "dot" "yes")
3601    (set_attr "length" "8,12")])
3603 (define_insn_and_split "*and<mode>3_2insn_dot2"
3604   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3605         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3606                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3607                     (const_int 0)))
3608    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3609         (and:GPR (match_dup 1)
3610                  (match_dup 2)))]
3611   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3612    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3613    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3614         || logical_const_operand (operands[2], <MODE>mode))"
3615   "#"
3616   "&& reload_completed"
3617   [(pc)]
3619   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3620   DONE;
3622   [(set_attr "type" "shift")
3623    (set_attr "dot" "yes")
3624    (set_attr "length" "8,12")])
3627 (define_expand "<code><mode>3"
3628   [(set (match_operand:SDI 0 "gpc_reg_operand")
3629         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3630                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3631   ""
3633   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3634     {
3635       rs6000_split_logical (operands, <CODE>, false, false, false);
3636       DONE;
3637     }
3639   if (non_logical_cint_operand (operands[2], <MODE>mode))
3640     {
3641       rtx tmp = ((!can_create_pseudo_p ()
3642                   || rtx_equal_p (operands[0], operands[1]))
3643                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3645       HOST_WIDE_INT value = INTVAL (operands[2]);
3646       HOST_WIDE_INT lo = value & 0xffff;
3647       HOST_WIDE_INT hi = value - lo;
3649       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3650       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3651       DONE;
3652     }
3654   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3655     operands[2] = force_reg (<MODE>mode, operands[2]);
3658 (define_split
3659   [(set (match_operand:GPR 0 "gpc_reg_operand")
3660         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3661                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3662   ""
3663   [(set (match_dup 3)
3664         (iorxor:GPR (match_dup 1)
3665                     (match_dup 4)))
3666    (set (match_dup 0)
3667         (iorxor:GPR (match_dup 3)
3668                     (match_dup 5)))]
3670   operands[3] = ((!can_create_pseudo_p ()
3671                   || rtx_equal_p (operands[0], operands[1]))
3672                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3674   HOST_WIDE_INT value = INTVAL (operands[2]);
3675   HOST_WIDE_INT lo = value & 0xffff;
3676   HOST_WIDE_INT hi = value - lo;
3678   operands[4] = GEN_INT (hi);
3679   operands[5] = GEN_INT (lo);
3682 (define_insn "*bool<mode>3_imm"
3683   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3684         (match_operator:GPR 3 "boolean_or_operator"
3685          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3686           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3687   ""
3688   "%q3i%e2 %0,%1,%u2"
3689   [(set_attr "type" "logical")])
3691 (define_insn "*bool<mode>3"
3692   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3693         (match_operator:GPR 3 "boolean_operator"
3694          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3695           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3696   ""
3697   "%q3 %0,%1,%2"
3698   [(set_attr "type" "logical")])
3700 (define_insn_and_split "*bool<mode>3_dot"
3701   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3702         (compare:CC (match_operator:GPR 3 "boolean_operator"
3703          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3704           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3705          (const_int 0)))
3706    (clobber (match_scratch:GPR 0 "=r,r"))]
3707   "<MODE>mode == Pmode"
3708   "@
3709    %q3. %0,%1,%2
3710    #"
3711   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3712   [(set (match_dup 0)
3713         (match_dup 3))
3714    (set (match_dup 4)
3715         (compare:CC (match_dup 0)
3716                     (const_int 0)))]
3717   ""
3718   [(set_attr "type" "logical")
3719    (set_attr "dot" "yes")
3720    (set_attr "length" "4,8")])
3722 (define_insn_and_split "*bool<mode>3_dot2"
3723   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3724         (compare:CC (match_operator:GPR 3 "boolean_operator"
3725          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3726           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3727          (const_int 0)))
3728    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3729         (match_dup 3))]
3730   "<MODE>mode == Pmode"
3731   "@
3732    %q3. %0,%1,%2
3733    #"
3734   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3735   [(set (match_dup 0)
3736         (match_dup 3))
3737    (set (match_dup 4)
3738         (compare:CC (match_dup 0)
3739                     (const_int 0)))]
3740   ""
3741   [(set_attr "type" "logical")
3742    (set_attr "dot" "yes")
3743    (set_attr "length" "4,8")])
3746 (define_insn "*boolc<mode>3"
3747   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3748         (match_operator:GPR 3 "boolean_operator"
3749          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3750           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3751   ""
3752   "%q3 %0,%1,%2"
3753   [(set_attr "type" "logical")])
3755 (define_insn_and_split "*boolc<mode>3_dot"
3756   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3757         (compare:CC (match_operator:GPR 3 "boolean_operator"
3758          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3759           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3760          (const_int 0)))
3761    (clobber (match_scratch:GPR 0 "=r,r"))]
3762   "<MODE>mode == Pmode"
3763   "@
3764    %q3. %0,%1,%2
3765    #"
3766   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3767   [(set (match_dup 0)
3768         (match_dup 3))
3769    (set (match_dup 4)
3770         (compare:CC (match_dup 0)
3771                     (const_int 0)))]
3772   ""
3773   [(set_attr "type" "logical")
3774    (set_attr "dot" "yes")
3775    (set_attr "length" "4,8")])
3777 (define_insn_and_split "*boolc<mode>3_dot2"
3778   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3779         (compare:CC (match_operator:GPR 3 "boolean_operator"
3780          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3781           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3782          (const_int 0)))
3783    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3784         (match_dup 3))]
3785   "<MODE>mode == Pmode"
3786   "@
3787    %q3. %0,%1,%2
3788    #"
3789   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3790   [(set (match_dup 0)
3791         (match_dup 3))
3792    (set (match_dup 4)
3793         (compare:CC (match_dup 0)
3794                     (const_int 0)))]
3795   ""
3796   [(set_attr "type" "logical")
3797    (set_attr "dot" "yes")
3798    (set_attr "length" "4,8")])
3801 (define_insn "*boolcc<mode>3"
3802   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3803         (match_operator:GPR 3 "boolean_operator"
3804          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3805           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3806   ""
3807   "%q3 %0,%1,%2"
3808   [(set_attr "type" "logical")])
3810 (define_insn_and_split "*boolcc<mode>3_dot"
3811   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3812         (compare:CC (match_operator:GPR 3 "boolean_operator"
3813          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3814           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3815          (const_int 0)))
3816    (clobber (match_scratch:GPR 0 "=r,r"))]
3817   "<MODE>mode == Pmode"
3818   "@
3819    %q3. %0,%1,%2
3820    #"
3821   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3822   [(set (match_dup 0)
3823         (match_dup 3))
3824    (set (match_dup 4)
3825         (compare:CC (match_dup 0)
3826                     (const_int 0)))]
3827   ""
3828   [(set_attr "type" "logical")
3829    (set_attr "dot" "yes")
3830    (set_attr "length" "4,8")])
3832 (define_insn_and_split "*boolcc<mode>3_dot2"
3833   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3834         (compare:CC (match_operator:GPR 3 "boolean_operator"
3835          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3836           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3837          (const_int 0)))
3838    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3839         (match_dup 3))]
3840   "<MODE>mode == Pmode"
3841   "@
3842    %q3. %0,%1,%2
3843    #"
3844   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3845   [(set (match_dup 0)
3846         (match_dup 3))
3847    (set (match_dup 4)
3848         (compare:CC (match_dup 0)
3849                     (const_int 0)))]
3850   ""
3851   [(set_attr "type" "logical")
3852    (set_attr "dot" "yes")
3853    (set_attr "length" "4,8")])
3856 ;; TODO: Should have dots of this as well.
3857 (define_insn "*eqv<mode>3"
3858   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3859         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3860                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3861   ""
3862   "eqv %0,%1,%2"
3863   [(set_attr "type" "logical")])
3865 ;; Rotate-and-mask and insert.
3867 (define_insn "*rotl<mode>3_mask"
3868   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3872                  (match_operand:GPR 3 "const_int_operand" "n")))]
3873   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3875   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3877   [(set_attr "type" "shift")
3878    (set_attr "maybe_var_shift" "yes")])
3880 (define_insn_and_split "*rotl<mode>3_mask_dot"
3881   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3882         (compare:CC
3883           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3884                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3885                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3886                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3887           (const_int 0)))
3888    (clobber (match_scratch:GPR 0 "=r,r"))]
3889   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3890    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3892   if (which_alternative == 0)
3893     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3894   else
3895     return "#";
3897   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3898   [(set (match_dup 0)
3899         (and:GPR (match_dup 4)
3900                  (match_dup 3)))
3901    (set (match_dup 5)
3902         (compare:CC (match_dup 0)
3903                     (const_int 0)))]
3904   ""
3905   [(set_attr "type" "shift")
3906    (set_attr "maybe_var_shift" "yes")
3907    (set_attr "dot" "yes")
3908    (set_attr "length" "4,8")])
3910 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3911   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3912         (compare:CC
3913           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3914                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3915                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3916                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3917           (const_int 0)))
3918    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3919         (and:GPR (match_dup 4)
3920                  (match_dup 3)))]
3921   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3922    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3924   if (which_alternative == 0)
3925     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3926   else
3927     return "#";
3929   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3930   [(set (match_dup 0)
3931         (and:GPR (match_dup 4)
3932                  (match_dup 3)))
3933    (set (match_dup 5)
3934         (compare:CC (match_dup 0)
3935                     (const_int 0)))]
3936   ""
3937   [(set_attr "type" "shift")
3938    (set_attr "maybe_var_shift" "yes")
3939    (set_attr "dot" "yes")
3940    (set_attr "length" "4,8")])
3942 ; Special case for less-than-0.  We can do it with just one machine
3943 ; instruction, but the generic optimizers do not realise it is cheap.
3944 (define_insn "*lt0_<mode>di"
3945   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3946         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3947                 (const_int 0)))]
3948   "TARGET_POWERPC64"
3949   "srdi %0,%1,63"
3950   [(set_attr "type" "shift")])
3952 (define_insn "*lt0_<mode>si"
3953   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3954         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3955                 (const_int 0)))]
3956   ""
3957   "rlwinm %0,%1,1,31,31"
3958   [(set_attr "type" "shift")])
3962 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3963 ; both are an AND so are the same precedence).
3964 (define_insn "*rotl<mode>3_insert"
3965   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3966         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3967                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3968                             (match_operand:SI 2 "const_int_operand" "n")])
3969                           (match_operand:GPR 3 "const_int_operand" "n"))
3970                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3971                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3972   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3973    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3975   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3977   [(set_attr "type" "insert")])
3978 ; FIXME: this needs an attr "size", so that the scheduler can see the
3979 ; difference between rlwimi and rldimi.  We also might want dot forms,
3980 ; but not for rlwimi on POWER4 and similar processors.
3982 (define_insn "*rotl<mode>3_insert_2"
3983   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3984         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3985                           (match_operand:GPR 6 "const_int_operand" "n"))
3986                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3987                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3988                             (match_operand:SI 2 "const_int_operand" "n")])
3989                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3990   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3991    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3993   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3995   [(set_attr "type" "insert")])
3997 ; There are also some forms without one of the ANDs.
3998 (define_insn "*rotl<mode>3_insert_3"
3999   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4000         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4001                           (match_operand:GPR 4 "const_int_operand" "n"))
4002                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4003                              (match_operand:SI 2 "const_int_operand" "n"))))]
4004   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4006   if (<MODE>mode == SImode)
4007     return "rlwimi %0,%1,%h2,0,31-%h2";
4008   else
4009     return "rldimi %0,%1,%H2,0";
4011   [(set_attr "type" "insert")])
4013 (define_insn "*rotl<mode>3_insert_4"
4014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4015         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4016                           (match_operand:GPR 4 "const_int_operand" "n"))
4017                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4018                                (match_operand:SI 2 "const_int_operand" "n"))))]
4019   "<MODE>mode == SImode &&
4020    GET_MODE_PRECISION (<MODE>mode)
4021    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4023   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4024                          - INTVAL (operands[2]));
4025   if (<MODE>mode == SImode)
4026     return "rlwimi %0,%1,%h2,32-%h2,31";
4027   else
4028     return "rldimi %0,%1,%H2,64-%H2";
4030   [(set_attr "type" "insert")])
4032 (define_insn "*rotlsi3_insert_5"
4033   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4034         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4035                         (match_operand:SI 2 "const_int_operand" "n,n"))
4036                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4037                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
4038   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4039    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4040    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4041   "@
4042    rlwimi %0,%3,0,%4
4043    rlwimi %0,%1,0,%2"
4044   [(set_attr "type" "insert")])
4046 (define_insn "*rotldi3_insert_6"
4047   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4048         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4049                         (match_operand:DI 2 "const_int_operand" "n"))
4050                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4051                         (match_operand:DI 4 "const_int_operand" "n"))))]
4052   "exact_log2 (-UINTVAL (operands[2])) > 0
4053    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4055   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4056   return "rldimi %0,%3,0,%5";
4058   [(set_attr "type" "insert")
4059    (set_attr "size" "64")])
4061 (define_insn "*rotldi3_insert_7"
4062   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4063         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4064                         (match_operand:DI 4 "const_int_operand" "n"))
4065                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4066                         (match_operand:DI 2 "const_int_operand" "n"))))]
4067   "exact_log2 (-UINTVAL (operands[2])) > 0
4068    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4070   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4071   return "rldimi %0,%3,0,%5";
4073   [(set_attr "type" "insert")
4074    (set_attr "size" "64")])
4077 ; This handles the important case of multiple-precision shifts.  There is
4078 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4079 (define_split
4080   [(set (match_operand:GPR 0 "gpc_reg_operand")
4081         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4082                              (match_operand:SI 3 "const_int_operand"))
4083                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4084                                (match_operand:SI 4 "const_int_operand"))))]
4085   "can_create_pseudo_p ()
4086    && INTVAL (operands[3]) + INTVAL (operands[4])
4087       >= GET_MODE_PRECISION (<MODE>mode)"
4088   [(set (match_dup 5)
4089         (lshiftrt:GPR (match_dup 2)
4090                       (match_dup 4)))
4091    (set (match_dup 0)
4092         (ior:GPR (and:GPR (match_dup 5)
4093                           (match_dup 6))
4094                  (ashift:GPR (match_dup 1)
4095                              (match_dup 3))))]
4097   unsigned HOST_WIDE_INT mask = 1;
4098   mask = (mask << INTVAL (operands[3])) - 1;
4099   operands[5] = gen_reg_rtx (<MODE>mode);
4100   operands[6] = GEN_INT (mask);
4103 (define_split
4104   [(set (match_operand:GPR 0 "gpc_reg_operand")
4105         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4106                                (match_operand:SI 4 "const_int_operand"))
4107                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4108                              (match_operand:SI 3 "const_int_operand"))))]
4109   "can_create_pseudo_p ()
4110    && INTVAL (operands[3]) + INTVAL (operands[4])
4111       >= GET_MODE_PRECISION (<MODE>mode)"
4112   [(set (match_dup 5)
4113         (lshiftrt:GPR (match_dup 2)
4114                       (match_dup 4)))
4115    (set (match_dup 0)
4116         (ior:GPR (and:GPR (match_dup 5)
4117                           (match_dup 6))
4118                  (ashift:GPR (match_dup 1)
4119                              (match_dup 3))))]
4121   unsigned HOST_WIDE_INT mask = 1;
4122   mask = (mask << INTVAL (operands[3])) - 1;
4123   operands[5] = gen_reg_rtx (<MODE>mode);
4124   operands[6] = GEN_INT (mask);
4128 ; Another important case is setting some bits to 1; we can do that with
4129 ; an insert instruction, in many cases.
4130 (define_insn_and_split "*ior<mode>_mask"
4131   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4132         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4133                  (match_operand:GPR 2 "const_int_operand" "n")))
4134    (clobber (match_scratch:GPR 3 "=r"))]
4135   "!logical_const_operand (operands[2], <MODE>mode)
4136    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4137   "#"
4138   "&& 1"
4139   [(set (match_dup 3)
4140         (const_int -1))
4141    (set (match_dup 0)
4142         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4143                                       (match_dup 4))
4144                           (match_dup 2))
4145                  (and:GPR (match_dup 1)
4146                           (match_dup 5))))]
4148   int nb, ne;
4149   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4150   if (GET_CODE (operands[3]) == SCRATCH)
4151     operands[3] = gen_reg_rtx (<MODE>mode);
4152   operands[4] = GEN_INT (ne);
4153   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4155   [(set_attr "type" "two")
4156    (set_attr "length" "8")])
4159 ; Yet another case is an rldimi with the second value coming from memory.
4160 ; The zero_extend that should become part of the rldimi is merged into the
4161 ; load from memory instead.  Split things properly again.
4162 (define_split
4163   [(set (match_operand:DI 0 "gpc_reg_operand")
4164         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4165                            (match_operand:SI 2 "const_int_operand"))
4166                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4167   "INTVAL (operands[2]) == <bits>"
4168   [(set (match_dup 4)
4169         (zero_extend:DI (match_dup 3)))
4170    (set (match_dup 0)
4171         (ior:DI (and:DI (match_dup 4)
4172                         (match_dup 5))
4173                 (ashift:DI (match_dup 1)
4174                            (match_dup 2))))]
4176   operands[4] = gen_reg_rtx (DImode);
4177   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4180 ; rlwimi, too.
4181 (define_split
4182   [(set (match_operand:SI 0 "gpc_reg_operand")
4183         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4184                            (match_operand:SI 2 "const_int_operand"))
4185                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4186   "INTVAL (operands[2]) == <bits>"
4187   [(set (match_dup 4)
4188         (zero_extend:SI (match_dup 3)))
4189    (set (match_dup 0)
4190         (ior:SI (and:SI (match_dup 4)
4191                         (match_dup 5))
4192                 (ashift:SI (match_dup 1)
4193                            (match_dup 2))))]
4195   operands[4] = gen_reg_rtx (SImode);
4196   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4200 ;; Now the simple shifts.
4202 (define_insn "rotl<mode>3"
4203   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4204         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4205                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4206   ""
4207   "rotl<wd>%I2 %0,%1,%<hH>2"
4208   [(set_attr "type" "shift")
4209    (set_attr "maybe_var_shift" "yes")])
4211 (define_insn "*rotlsi3_64"
4212   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4213         (zero_extend:DI
4214             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4215                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4216   "TARGET_POWERPC64"
4217   "rotlw%I2 %0,%1,%h2"
4218   [(set_attr "type" "shift")
4219    (set_attr "maybe_var_shift" "yes")])
4221 (define_insn_and_split "*rotl<mode>3_dot"
4222   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4223         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4224                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4225                     (const_int 0)))
4226    (clobber (match_scratch:GPR 0 "=r,r"))]
4227   "<MODE>mode == Pmode"
4228   "@
4229    rotl<wd>%I2. %0,%1,%<hH>2
4230    #"
4231   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4232   [(set (match_dup 0)
4233         (rotate:GPR (match_dup 1)
4234                     (match_dup 2)))
4235    (set (match_dup 3)
4236         (compare:CC (match_dup 0)
4237                     (const_int 0)))]
4238   ""
4239   [(set_attr "type" "shift")
4240    (set_attr "maybe_var_shift" "yes")
4241    (set_attr "dot" "yes")
4242    (set_attr "length" "4,8")])
4244 (define_insn_and_split "*rotl<mode>3_dot2"
4245   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4246         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4247                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4248                     (const_int 0)))
4249    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4250         (rotate:GPR (match_dup 1)
4251                     (match_dup 2)))]
4252   "<MODE>mode == Pmode"
4253   "@
4254    rotl<wd>%I2. %0,%1,%<hH>2
4255    #"
4256   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4257   [(set (match_dup 0)
4258         (rotate:GPR (match_dup 1)
4259                     (match_dup 2)))
4260    (set (match_dup 3)
4261         (compare:CC (match_dup 0)
4262                     (const_int 0)))]
4263   ""
4264   [(set_attr "type" "shift")
4265    (set_attr "maybe_var_shift" "yes")
4266    (set_attr "dot" "yes")
4267    (set_attr "length" "4,8")])
4270 (define_insn "ashl<mode>3"
4271   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4272         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4273                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4274   ""
4275   "sl<wd>%I2 %0,%1,%<hH>2"
4276   [(set_attr "type" "shift")
4277    (set_attr "maybe_var_shift" "yes")])
4279 (define_insn "*ashlsi3_64"
4280   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4281         (zero_extend:DI
4282             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4283                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4284   "TARGET_POWERPC64"
4285   "slw%I2 %0,%1,%h2"
4286   [(set_attr "type" "shift")
4287    (set_attr "maybe_var_shift" "yes")])
4289 (define_insn_and_split "*ashl<mode>3_dot"
4290   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4291         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4292                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4293                     (const_int 0)))
4294    (clobber (match_scratch:GPR 0 "=r,r"))]
4295   "<MODE>mode == Pmode"
4296   "@
4297    sl<wd>%I2. %0,%1,%<hH>2
4298    #"
4299   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4300   [(set (match_dup 0)
4301         (ashift:GPR (match_dup 1)
4302                     (match_dup 2)))
4303    (set (match_dup 3)
4304         (compare:CC (match_dup 0)
4305                     (const_int 0)))]
4306   ""
4307   [(set_attr "type" "shift")
4308    (set_attr "maybe_var_shift" "yes")
4309    (set_attr "dot" "yes")
4310    (set_attr "length" "4,8")])
4312 (define_insn_and_split "*ashl<mode>3_dot2"
4313   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4314         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4315                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4316                     (const_int 0)))
4317    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4318         (ashift:GPR (match_dup 1)
4319                     (match_dup 2)))]
4320   "<MODE>mode == Pmode"
4321   "@
4322    sl<wd>%I2. %0,%1,%<hH>2
4323    #"
4324   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4325   [(set (match_dup 0)
4326         (ashift:GPR (match_dup 1)
4327                     (match_dup 2)))
4328    (set (match_dup 3)
4329         (compare:CC (match_dup 0)
4330                     (const_int 0)))]
4331   ""
4332   [(set_attr "type" "shift")
4333    (set_attr "maybe_var_shift" "yes")
4334    (set_attr "dot" "yes")
4335    (set_attr "length" "4,8")])
4337 ;; Pretend we have a memory form of extswsli until register allocation is done
4338 ;; so that we use LWZ to load the value from memory, instead of LWA.
4339 (define_insn_and_split "ashdi3_extswsli"
4340   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4341         (ashift:DI
4342          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4343          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4344   "TARGET_EXTSWSLI"
4345   "@
4346    extswsli %0,%1,%2
4347    #"
4348   "&& reload_completed && MEM_P (operands[1])"
4349   [(set (match_dup 3)
4350         (match_dup 1))
4351    (set (match_dup 0)
4352         (ashift:DI (sign_extend:DI (match_dup 3))
4353                    (match_dup 2)))]
4355   operands[3] = gen_lowpart (SImode, operands[0]);
4357   [(set_attr "type" "shift")
4358    (set_attr "maybe_var_shift" "no")])
4361 (define_insn_and_split "ashdi3_extswsli_dot"
4362   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4363         (compare:CC
4364          (ashift:DI
4365           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4366           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4367          (const_int 0)))
4368    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4369   "TARGET_EXTSWSLI"
4370   "@
4371    extswsli. %0,%1,%2
4372    #
4373    #
4374    #"
4375   "&& reload_completed
4376    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4377        || memory_operand (operands[1], SImode))"
4378   [(pc)]
4380   rtx dest = operands[0];
4381   rtx src = operands[1];
4382   rtx shift = operands[2];
4383   rtx cr = operands[3];
4384   rtx src2;
4386   if (!MEM_P (src))
4387     src2 = src;
4388   else
4389     {
4390       src2 = gen_lowpart (SImode, dest);
4391       emit_move_insn (src2, src);
4392     }
4394   if (REGNO (cr) == CR0_REGNO)
4395     {
4396       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4397       DONE;
4398     }
4400   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4401   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4402   DONE;
4404   [(set_attr "type" "shift")
4405    (set_attr "maybe_var_shift" "no")
4406    (set_attr "dot" "yes")
4407    (set_attr "length" "4,8,8,12")])
4409 (define_insn_and_split "ashdi3_extswsli_dot2"
4410   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4411         (compare:CC
4412          (ashift:DI
4413           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4414           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4415          (const_int 0)))
4416    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4417         (ashift:DI (sign_extend:DI (match_dup 1))
4418                    (match_dup 2)))]
4419   "TARGET_EXTSWSLI"
4420   "@
4421    extswsli. %0,%1,%2
4422    #
4423    #
4424    #"
4425   "&& reload_completed
4426    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4427        || memory_operand (operands[1], SImode))"
4428   [(pc)]
4430   rtx dest = operands[0];
4431   rtx src = operands[1];
4432   rtx shift = operands[2];
4433   rtx cr = operands[3];
4434   rtx src2;
4436   if (!MEM_P (src))
4437     src2 = src;
4438   else
4439     {
4440       src2 = gen_lowpart (SImode, dest);
4441       emit_move_insn (src2, src);
4442     }
4444   if (REGNO (cr) == CR0_REGNO)
4445     {
4446       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4447       DONE;
4448     }
4450   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4451   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4452   DONE;
4454   [(set_attr "type" "shift")
4455    (set_attr "maybe_var_shift" "no")
4456    (set_attr "dot" "yes")
4457    (set_attr "length" "4,8,8,12")])
4459 (define_insn "lshr<mode>3"
4460   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4461         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4462                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4463   ""
4464   "sr<wd>%I2 %0,%1,%<hH>2"
4465   [(set_attr "type" "shift")
4466    (set_attr "maybe_var_shift" "yes")])
4468 (define_insn "*lshrsi3_64"
4469   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4470         (zero_extend:DI
4471             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4472                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4473   "TARGET_POWERPC64"
4474   "srw%I2 %0,%1,%h2"
4475   [(set_attr "type" "shift")
4476    (set_attr "maybe_var_shift" "yes")])
4478 (define_insn_and_split "*lshr<mode>3_dot"
4479   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4480         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4481                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4482                     (const_int 0)))
4483    (clobber (match_scratch:GPR 0 "=r,r"))]
4484   "<MODE>mode == Pmode"
4485   "@
4486    sr<wd>%I2. %0,%1,%<hH>2
4487    #"
4488   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4489   [(set (match_dup 0)
4490         (lshiftrt:GPR (match_dup 1)
4491                       (match_dup 2)))
4492    (set (match_dup 3)
4493         (compare:CC (match_dup 0)
4494                     (const_int 0)))]
4495   ""
4496   [(set_attr "type" "shift")
4497    (set_attr "maybe_var_shift" "yes")
4498    (set_attr "dot" "yes")
4499    (set_attr "length" "4,8")])
4501 (define_insn_and_split "*lshr<mode>3_dot2"
4502   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4503         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4504                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4505                     (const_int 0)))
4506    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4507         (lshiftrt:GPR (match_dup 1)
4508                       (match_dup 2)))]
4509   "<MODE>mode == Pmode"
4510   "@
4511    sr<wd>%I2. %0,%1,%<hH>2
4512    #"
4513   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4514   [(set (match_dup 0)
4515         (lshiftrt:GPR (match_dup 1)
4516                       (match_dup 2)))
4517    (set (match_dup 3)
4518         (compare:CC (match_dup 0)
4519                     (const_int 0)))]
4520   ""
4521   [(set_attr "type" "shift")
4522    (set_attr "maybe_var_shift" "yes")
4523    (set_attr "dot" "yes")
4524    (set_attr "length" "4,8")])
4527 (define_insn "ashr<mode>3"
4528   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4529         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4530                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4531    (clobber (reg:GPR CA_REGNO))]
4532   ""
4533   "sra<wd>%I2 %0,%1,%<hH>2"
4534   [(set_attr "type" "shift")
4535    (set_attr "maybe_var_shift" "yes")])
4537 (define_insn "*ashrsi3_64"
4538   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4539         (sign_extend:DI
4540             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4541                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4542    (clobber (reg:SI CA_REGNO))]
4543   "TARGET_POWERPC64"
4544   "sraw%I2 %0,%1,%h2"
4545   [(set_attr "type" "shift")
4546    (set_attr "maybe_var_shift" "yes")])
4548 (define_insn_and_split "*ashr<mode>3_dot"
4549   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4550         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4551                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4552                     (const_int 0)))
4553    (clobber (match_scratch:GPR 0 "=r,r"))
4554    (clobber (reg:GPR CA_REGNO))]
4555   "<MODE>mode == Pmode"
4556   "@
4557    sra<wd>%I2. %0,%1,%<hH>2
4558    #"
4559   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4560   [(parallel [(set (match_dup 0)
4561                    (ashiftrt:GPR (match_dup 1)
4562                                  (match_dup 2)))
4563               (clobber (reg:GPR CA_REGNO))])
4564    (set (match_dup 3)
4565         (compare:CC (match_dup 0)
4566                     (const_int 0)))]
4567   ""
4568   [(set_attr "type" "shift")
4569    (set_attr "maybe_var_shift" "yes")
4570    (set_attr "dot" "yes")
4571    (set_attr "length" "4,8")])
4573 (define_insn_and_split "*ashr<mode>3_dot2"
4574   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4575         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4576                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4577                     (const_int 0)))
4578    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4579         (ashiftrt:GPR (match_dup 1)
4580                       (match_dup 2)))
4581    (clobber (reg:GPR CA_REGNO))]
4582   "<MODE>mode == Pmode"
4583   "@
4584    sra<wd>%I2. %0,%1,%<hH>2
4585    #"
4586   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4587   [(parallel [(set (match_dup 0)
4588                    (ashiftrt:GPR (match_dup 1)
4589                                  (match_dup 2)))
4590               (clobber (reg:GPR CA_REGNO))])
4591    (set (match_dup 3)
4592         (compare:CC (match_dup 0)
4593                     (const_int 0)))]
4594   ""
4595   [(set_attr "type" "shift")
4596    (set_attr "maybe_var_shift" "yes")
4597    (set_attr "dot" "yes")
4598    (set_attr "length" "4,8")])
4600 ;; Builtins to replace a division to generate FRE reciprocal estimate
4601 ;; instructions and the necessary fixup instructions
4602 (define_expand "recip<mode>3"
4603   [(match_operand:RECIPF 0 "gpc_reg_operand")
4604    (match_operand:RECIPF 1 "gpc_reg_operand")
4605    (match_operand:RECIPF 2 "gpc_reg_operand")]
4606   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4608    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4609    DONE;
4612 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4613 ;; hardware division.  This is only done before register allocation and with
4614 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4615 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4616 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4617 (define_split
4618   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4619         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4620                     (match_operand 2 "gpc_reg_operand")))]
4621   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4622    && can_create_pseudo_p () && flag_finite_math_only
4623    && !flag_trapping_math && flag_reciprocal_math"
4624   [(const_int 0)]
4626   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4627   DONE;
4630 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4631 ;; appropriate fixup.
4632 (define_expand "rsqrt<mode>2"
4633   [(match_operand:RECIPF 0 "gpc_reg_operand")
4634    (match_operand:RECIPF 1 "gpc_reg_operand")]
4635   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4637   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4638   DONE;
4641 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4642 ;; modes here, and also add in conditional vsx/power8-vector support to access
4643 ;; values in the traditional Altivec registers if the appropriate
4644 ;; -mupper-regs-{df,sf} option is enabled.
4646 (define_expand "abs<mode>2"
4647   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4648         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4649   "TARGET_HARD_FLOAT"
4650   "")
4652 (define_insn "*abs<mode>2_fpr"
4653   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4654         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4655   "TARGET_HARD_FLOAT"
4656   "@
4657    fabs %0,%1
4658    xsabsdp %x0,%x1"
4659   [(set_attr "type" "fpsimple")])
4661 (define_insn "*nabs<mode>2_fpr"
4662   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4663         (neg:SFDF
4664          (abs:SFDF
4665           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4666   "TARGET_HARD_FLOAT"
4667   "@
4668    fnabs %0,%1
4669    xsnabsdp %x0,%x1"
4670   [(set_attr "type" "fpsimple")])
4672 (define_expand "neg<mode>2"
4673   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4674         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4675   "TARGET_HARD_FLOAT"
4676   "")
4678 (define_insn "*neg<mode>2_fpr"
4679   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4680         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4681   "TARGET_HARD_FLOAT"
4682   "@
4683    fneg %0,%1
4684    xsnegdp %x0,%x1"
4685   [(set_attr "type" "fpsimple")])
4687 (define_expand "add<mode>3"
4688   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4689         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4690                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4691   "TARGET_HARD_FLOAT"
4692   "")
4694 (define_insn "*add<mode>3_fpr"
4695   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4696         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4697                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4698   "TARGET_HARD_FLOAT"
4699   "@
4700    fadd<s> %0,%1,%2
4701    xsadd<sd>p %x0,%x1,%x2"
4702   [(set_attr "type" "fp")
4703    (set_attr "isa" "*,<Fisa>")])
4705 (define_expand "sub<mode>3"
4706   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4707         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4708                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4709   "TARGET_HARD_FLOAT"
4710   "")
4712 (define_insn "*sub<mode>3_fpr"
4713   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4714         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4715                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4716   "TARGET_HARD_FLOAT"
4717   "@
4718    fsub<s> %0,%1,%2
4719    xssub<sd>p %x0,%x1,%x2"
4720   [(set_attr "type" "fp")
4721    (set_attr "isa" "*,<Fisa>")])
4723 (define_expand "mul<mode>3"
4724   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4725         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4726                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4727   "TARGET_HARD_FLOAT"
4728   "")
4730 (define_insn "*mul<mode>3_fpr"
4731   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4732         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4733                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4734   "TARGET_HARD_FLOAT"
4735   "@
4736    fmul<s> %0,%1,%2
4737    xsmul<sd>p %x0,%x1,%x2"
4738   [(set_attr "type" "dmul")
4739    (set_attr "isa" "*,<Fisa>")])
4741 (define_expand "div<mode>3"
4742   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4743         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4744                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4745   "TARGET_HARD_FLOAT"
4747   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4748       && can_create_pseudo_p () && flag_finite_math_only
4749       && !flag_trapping_math && flag_reciprocal_math)
4750     {
4751       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4752       DONE;
4753     }
4756 (define_insn "*div<mode>3_fpr"
4757   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4758         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4759                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4760   "TARGET_HARD_FLOAT"
4761   "@
4762    fdiv<s> %0,%1,%2
4763    xsdiv<sd>p %x0,%x1,%x2"
4764   [(set_attr "type" "<sd>div")
4765    (set_attr "isa" "*,<Fisa>")])
4767 (define_insn "*sqrt<mode>2_internal"
4768   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4769         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4770   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4771   "@
4772    fsqrt<s> %0,%1
4773    xssqrt<sd>p %x0,%x1"
4774   [(set_attr "type" "<sd>sqrt")
4775    (set_attr "isa" "*,<Fisa>")])
4777 (define_expand "sqrt<mode>2"
4778   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4779         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4780   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4782   if (<MODE>mode == SFmode
4783       && TARGET_RECIP_PRECISION
4784       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4785       && !optimize_function_for_size_p (cfun)
4786       && flag_finite_math_only && !flag_trapping_math
4787       && flag_unsafe_math_optimizations)
4788     {
4789       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4790       DONE;
4791     }
4794 ;; Floating point reciprocal approximation
4795 (define_insn "fre<sd>"
4796   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4797         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4798                      UNSPEC_FRES))]
4799   "TARGET_<FFRE>"
4800   "@
4801    fre<s> %0,%1
4802    xsre<sd>p %x0,%x1"
4803   [(set_attr "type" "fp")
4804    (set_attr "isa" "*,<Fisa>")])
4806 (define_insn "*rsqrt<mode>2"
4807   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4808         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4809                      UNSPEC_RSQRT))]
4810   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4811   "@
4812    frsqrte<s> %0,%1
4813    xsrsqrte<sd>p %x0,%x1"
4814   [(set_attr "type" "fp")
4815    (set_attr "isa" "*,<Fisa>")])
4817 ;; Floating point comparisons
4818 (define_insn "*cmp<mode>_fpr"
4819   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4820         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4821                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4822   "TARGET_HARD_FLOAT"
4823   "@
4824    fcmpu %0,%1,%2
4825    xscmpudp %0,%x1,%x2"
4826   [(set_attr "type" "fpcompare")
4827    (set_attr "isa" "*,<Fisa>")])
4829 ;; Floating point conversions
4830 (define_expand "extendsfdf2"
4831   [(set (match_operand:DF 0 "gpc_reg_operand")
4832         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4833   "TARGET_HARD_FLOAT"
4835   if (HONOR_SNANS (SFmode))
4836     operands[1] = force_reg (SFmode, operands[1]);
4839 (define_insn_and_split "*extendsfdf2_fpr"
4840   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4841         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4842   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4843   "@
4844    #
4845    fmr %0,%1
4846    lfs%U1%X1 %0,%1
4847    #
4848    xscpsgndp %x0,%x1,%x1
4849    lxsspx %x0,%y1
4850    lxssp %0,%1"
4851   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4852   [(const_int 0)]
4854   emit_note (NOTE_INSN_DELETED);
4855   DONE;
4857   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4858    (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4860 (define_insn "*extendsfdf2_snan"
4861   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4862         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4863   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4864   "@
4865    frsp %0,%1
4866    xsrsp %x0,%x1"
4867   [(set_attr "type" "fp")
4868    (set_attr "isa" "*,p8v")])
4870 (define_expand "truncdfsf2"
4871   [(set (match_operand:SF 0 "gpc_reg_operand")
4872         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4873   "TARGET_HARD_FLOAT"
4874   "")
4876 (define_insn "*truncdfsf2_fpr"
4877   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4878         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4879   "TARGET_HARD_FLOAT"
4880   "@
4881    frsp %0,%1
4882    xsrsp %x0,%x1"
4883   [(set_attr "type" "fp")
4884    (set_attr "isa" "*,p8v")])
4886 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4887 ;; builtins.c and optabs.c that are not correct for IBM long double
4888 ;; when little-endian.
4889 (define_expand "signbit<mode>2"
4890   [(set (match_dup 2)
4891         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4892    (set (match_dup 3)
4893         (subreg:DI (match_dup 2) 0))
4894    (set (match_dup 4)
4895         (match_dup 5))
4896    (set (match_operand:SI 0 "gpc_reg_operand")
4897         (match_dup 6))]
4898   "TARGET_HARD_FLOAT
4899    && (!FLOAT128_IEEE_P (<MODE>mode)
4900        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4902   if (FLOAT128_IEEE_P (<MODE>mode))
4903     {
4904       rtx dest = operands[0];
4905       rtx src = operands[1];
4906       rtx tmp = gen_reg_rtx (DImode);
4907       rtx dest_di = gen_lowpart (DImode, dest);
4909       emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4910       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4911       DONE;
4912     }
4913   operands[2] = gen_reg_rtx (DFmode);
4914   operands[3] = gen_reg_rtx (DImode);
4915   if (TARGET_POWERPC64)
4916     {
4917       operands[4] = gen_reg_rtx (DImode);
4918       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4919       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4920                                     WORDS_BIG_ENDIAN ? 4 : 0);
4921     }
4922   else
4923     {
4924       operands[4] = gen_reg_rtx (SImode);
4925       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4926                                     WORDS_BIG_ENDIAN ? 0 : 4);
4927       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4928     }
4931 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4932 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4933 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4934 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4936 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4937 ;; split allows the post reload phases to eliminate the move, and do the shift
4938 ;; directly with the register that contains the signbit.
4939 (define_insn_and_split "@signbit<mode>2_dm"
4940   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4941         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4942                    UNSPEC_SIGNBIT))]
4943   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4944   "@
4945    mfvsrd %0,%x1
4946    #"
4947   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4948   [(set (match_dup 0)
4949         (match_dup 2))]
4951   operands[2] = gen_highpart (DImode, operands[1]);
4953  [(set_attr "type" "mftgpr,*")])
4955 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4956 ;; register and then doing a direct move if the value comes from memory.  On
4957 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4958 (define_insn_and_split "*signbit<mode>2_dm_mem"
4959   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4960         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4961                    UNSPEC_SIGNBIT))]
4962   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4963   "#"
4964   "&& 1"
4965   [(set (match_dup 0)
4966         (match_dup 2))]
4968   rtx dest = operands[0];
4969   rtx src = operands[1];
4970   rtx addr = XEXP (src, 0);
4972   if (WORDS_BIG_ENDIAN)
4973     operands[2] = adjust_address (src, DImode, 0);
4975   else if (REG_P (addr) || SUBREG_P (addr))
4976     operands[2] = adjust_address (src, DImode, 8);
4978   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4979            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4980     operands[2] = adjust_address (src, DImode, 8);
4982   else
4983     {
4984       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4985       emit_insn (gen_rtx_SET (tmp, addr));
4986       operands[2] = change_address (src, DImode,
4987                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4988     }
4991 (define_expand "copysign<mode>3"
4992   [(set (match_dup 3)
4993         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4994    (set (match_dup 4)
4995         (neg:SFDF (abs:SFDF (match_dup 1))))
4996    (set (match_operand:SFDF 0 "gpc_reg_operand")
4997         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4998                                (match_dup 5))
4999                          (match_dup 3)
5000                          (match_dup 4)))]
5001   "TARGET_HARD_FLOAT
5002    && ((TARGET_PPC_GFXOPT
5003         && !HONOR_NANS (<MODE>mode)
5004         && !HONOR_SIGNED_ZEROS (<MODE>mode))
5005        || TARGET_CMPB
5006        || VECTOR_UNIT_VSX_P (<MODE>mode))"
5008   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5009     {
5010       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5011                                              operands[2]));
5012       DONE;
5013     }
5015    operands[3] = gen_reg_rtx (<MODE>mode);
5016    operands[4] = gen_reg_rtx (<MODE>mode);
5017    operands[5] = CONST0_RTX (<MODE>mode);
5018   })
5020 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5021 ;; compiler from optimizing -0.0
5022 (define_insn "copysign<mode>3_fcpsgn"
5023   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5024         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5025                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5026                      UNSPEC_COPYSIGN))]
5027   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5028   "@
5029    fcpsgn %0,%2,%1
5030    xscpsgndp %x0,%x2,%x1"
5031   [(set_attr "type" "fpsimple")])
5033 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5034 ;; fsel instruction and some auxiliary computations.  Then we just have a
5035 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5036 ;; combine.
5037 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5038 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5039 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5040 ;; define_splits to make them if made by combine.  On VSX machines we have the
5041 ;; min/max instructions.
5043 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5044 ;; to allow either DF/SF to use only traditional registers.
5046 (define_expand "s<minmax><mode>3"
5047   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5048         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5049                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5050   "TARGET_MINMAX"
5052   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5053   DONE;
5056 (define_insn "*s<minmax><mode>3_vsx"
5057   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5058         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5059                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5060   "TARGET_VSX && TARGET_HARD_FLOAT"
5062   return (TARGET_P9_MINMAX
5063           ? "xs<minmax>cdp %x0,%x1,%x2"
5064           : "xs<minmax>dp %x0,%x1,%x2");
5066   [(set_attr "type" "fp")])
5068 ;; The conditional move instructions allow us to perform max and min operations
5069 ;; even when we don't have the appropriate max/min instruction using the FSEL
5070 ;; instruction.
5072 (define_insn_and_split "*s<minmax><mode>3_fpr"
5073   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5074         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5075                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5076   "!TARGET_VSX && TARGET_MINMAX"
5077   "#"
5078   "&& 1"
5079   [(const_int 0)]
5081   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5082   DONE;
5085 (define_expand "mov<mode>cc"
5086    [(set (match_operand:GPR 0 "gpc_reg_operand")
5087          (if_then_else:GPR (match_operand 1 "comparison_operator")
5088                            (match_operand:GPR 2 "gpc_reg_operand")
5089                            (match_operand:GPR 3 "gpc_reg_operand")))]
5090   "TARGET_ISEL"
5092   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5093     DONE;
5094   else
5095     FAIL;
5098 ;; We use the BASE_REGS for the isel input operands because, if rA is
5099 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5100 ;; because we may switch the operands and rB may end up being rA.
5102 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5103 ;; leave out the mode in operand 4 and use one pattern, but reload can
5104 ;; change the mode underneath our feet and then gets confused trying
5105 ;; to reload the value.
5106 (define_mode_iterator CCEITHER [CC CCUNS])
5107 (define_mode_attr un [(CC "") (CCUNS "un")])
5108 (define_insn "isel_<un>signed_<GPR:mode>"
5109   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5110         (if_then_else:GPR
5111          (match_operator 1 "scc_comparison_operator"
5112                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5113                           (const_int 0)])
5114          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5115          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5116   "TARGET_ISEL"
5117   "isel %0,%2,%3,%j1"
5118   [(set_attr "type" "isel")])
5120 ;; These patterns can be useful for combine; they let combine know that
5121 ;; isel can handle reversed comparisons so long as the operands are
5122 ;; registers.
5124 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5125   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5126         (if_then_else:GPR
5127          (match_operator 1 "scc_rev_comparison_operator"
5128                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5129                           (const_int 0)])
5130          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5131          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5132   "TARGET_ISEL"
5134   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5135   return "isel %0,%3,%2,%j1";
5137   [(set_attr "type" "isel")])
5139 ;; Floating point conditional move
5140 (define_expand "mov<mode>cc"
5141    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5142          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5143                             (match_operand:SFDF 2 "gpc_reg_operand")
5144                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5145   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5147   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5148     DONE;
5149   else
5150     FAIL;
5153 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5154   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5155         (if_then_else:SFDF
5156          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5157              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5158          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5159          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5160   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5161   "fsel %0,%1,%2,%3"
5162   [(set_attr "type" "fp")])
5164 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5165   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5166         (if_then_else:SFDF
5167          (match_operator:CCFP 1 "fpmask_comparison_operator"
5168                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5169                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5170          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5171          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5172    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5173   "TARGET_P9_MINMAX"
5174   "#"
5175   ""
5176   [(set (match_dup 6)
5177         (if_then_else:V2DI (match_dup 1)
5178                            (match_dup 7)
5179                            (match_dup 8)))
5180    (set (match_dup 0)
5181         (if_then_else:SFDF (ne (match_dup 6)
5182                                (match_dup 8))
5183                            (match_dup 4)
5184                            (match_dup 5)))]
5186   if (GET_CODE (operands[6]) == SCRATCH)
5187     operands[6] = gen_reg_rtx (V2DImode);
5189   operands[7] = CONSTM1_RTX (V2DImode);
5190   operands[8] = CONST0_RTX (V2DImode);
5192  [(set_attr "length" "8")
5193   (set_attr "type" "vecperm")])
5195 ;; Handle inverting the fpmask comparisons.
5196 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5197   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5198         (if_then_else:SFDF
5199          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5200                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5201                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5202          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5203          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5204    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5205   "TARGET_P9_MINMAX"
5206   "#"
5207   "&& 1"
5208   [(set (match_dup 6)
5209         (if_then_else:V2DI (match_dup 9)
5210                            (match_dup 7)
5211                            (match_dup 8)))
5212    (set (match_dup 0)
5213         (if_then_else:SFDF (ne (match_dup 6)
5214                                (match_dup 8))
5215                            (match_dup 5)
5216                            (match_dup 4)))]
5218   rtx op1 = operands[1];
5219   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5221   if (GET_CODE (operands[6]) == SCRATCH)
5222     operands[6] = gen_reg_rtx (V2DImode);
5224   operands[7] = CONSTM1_RTX (V2DImode);
5225   operands[8] = CONST0_RTX (V2DImode);
5227   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5229  [(set_attr "length" "8")
5230   (set_attr "type" "vecperm")])
5232 (define_insn "*fpmask<mode>"
5233   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5234         (if_then_else:V2DI
5235          (match_operator:CCFP 1 "fpmask_comparison_operator"
5236                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5237                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5238          (match_operand:V2DI 4 "all_ones_constant" "")
5239          (match_operand:V2DI 5 "zero_constant" "")))]
5240   "TARGET_P9_MINMAX"
5241   "xscmp%V1dp %x0,%x2,%x3"
5242   [(set_attr "type" "fpcompare")])
5244 (define_insn "*xxsel<mode>"
5245   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5246         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5247                                (match_operand:V2DI 2 "zero_constant" ""))
5248                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5249                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5250   "TARGET_P9_MINMAX"
5251   "xxsel %x0,%x4,%x3,%x1"
5252   [(set_attr "type" "vecmove")])
5255 ;; Conversions to and from floating-point.
5257 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5258 ; don't want to support putting SImode in FPR registers.
5259 (define_insn "lfiwax"
5260   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5261         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5262                    UNSPEC_LFIWAX))]
5263   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5264   "@
5265    lfiwax %0,%y1
5266    lxsiwax %x0,%y1
5267    mtvsrwa %x0,%1
5268    vextsw2d %0,%1"
5269   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5270    (set_attr "isa" "*,p8v,p8v,p9v")])
5272 ; This split must be run before register allocation because it allocates the
5273 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5274 ; it earlier to allow for the combiner to merge insns together where it might
5275 ; not be needed and also in case the insns are deleted as dead code.
5277 (define_insn_and_split "floatsi<mode>2_lfiwax"
5278   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5279         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5280    (clobber (match_scratch:DI 2 "=d,wa"))]
5281   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5282    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5283   "#"
5284   ""
5285   [(pc)]
5287   rtx dest = operands[0];
5288   rtx src = operands[1];
5289   rtx tmp;
5291   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5292     tmp = convert_to_mode (DImode, src, false);
5293   else
5294     {
5295       tmp = operands[2];
5296       if (GET_CODE (tmp) == SCRATCH)
5297         tmp = gen_reg_rtx (DImode);
5298       if (MEM_P (src))
5299         {
5300           src = rs6000_force_indexed_or_indirect_mem (src);
5301           emit_insn (gen_lfiwax (tmp, src));
5302         }
5303       else
5304         {
5305           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5306           emit_move_insn (stack, src);
5307           emit_insn (gen_lfiwax (tmp, stack));
5308         }
5309     }
5310   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5311   DONE;
5313   [(set_attr "length" "12")
5314    (set_attr "type" "fpload")])
5316 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5317   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5318         (float:SFDF
5319          (sign_extend:DI
5320           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5321    (clobber (match_scratch:DI 2 "=d,wa"))]
5322   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5323   "#"
5324   ""
5325   [(pc)]
5327   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5328   if (GET_CODE (operands[2]) == SCRATCH)
5329     operands[2] = gen_reg_rtx (DImode);
5330   if (TARGET_P8_VECTOR)
5331     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5332   else
5333     emit_insn (gen_lfiwax (operands[2], operands[1]));
5334   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5335   DONE;
5337   [(set_attr "length" "8")
5338    (set_attr "type" "fpload")])
5340 (define_insn "lfiwzx"
5341   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5342         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5343                    UNSPEC_LFIWZX))]
5344   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5345   "@
5346    lfiwzx %0,%y1
5347    lxsiwzx %x0,%y1
5348    mtvsrwz %x0,%1
5349    xxextractuw %x0,%x1,4"
5350   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5351    (set_attr "isa" "*,p8v,p8v,p9v")])
5353 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5354   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5355         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5356    (clobber (match_scratch:DI 2 "=d,wa"))]
5357   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5358   "#"
5359   ""
5360   [(pc)]
5362   rtx dest = operands[0];
5363   rtx src = operands[1];
5364   rtx tmp;
5366   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5367     tmp = convert_to_mode (DImode, src, true);
5368   else
5369     {
5370       tmp = operands[2];
5371       if (GET_CODE (tmp) == SCRATCH)
5372         tmp = gen_reg_rtx (DImode);
5373       if (MEM_P (src))
5374         {
5375           src = rs6000_force_indexed_or_indirect_mem (src);
5376           emit_insn (gen_lfiwzx (tmp, src));
5377         }
5378       else
5379         {
5380           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5381           emit_move_insn (stack, src);
5382           emit_insn (gen_lfiwzx (tmp, stack));
5383         }
5384     }
5385   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5386   DONE;
5388   [(set_attr "length" "12")
5389    (set_attr "type" "fpload")])
5391 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5392   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5393         (unsigned_float:SFDF
5394          (zero_extend:DI
5395           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5396    (clobber (match_scratch:DI 2 "=d,wa"))]
5397   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5398   "#"
5399   ""
5400   [(pc)]
5402   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5403   if (GET_CODE (operands[2]) == SCRATCH)
5404     operands[2] = gen_reg_rtx (DImode);
5405   if (TARGET_P8_VECTOR)
5406     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5407   else
5408     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5409   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5410   DONE;
5412   [(set_attr "length" "8")
5413    (set_attr "type" "fpload")])
5415 ; For each of these conversions, there is a define_expand, a define_insn
5416 ; with a '#' template, and a define_split (with C code).  The idea is
5417 ; to allow constant folding with the template of the define_insn,
5418 ; then to have the insns split later (between sched1 and final).
5420 (define_expand "floatsidf2"
5421   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5422                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5423               (use (match_dup 2))
5424               (use (match_dup 3))
5425               (clobber (match_dup 4))
5426               (clobber (match_dup 5))
5427               (clobber (match_dup 6))])]
5428   "TARGET_HARD_FLOAT"
5430   if (TARGET_LFIWAX && TARGET_FCFID)
5431     {
5432       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5433       DONE;
5434     }
5435   else if (TARGET_FCFID)
5436     {
5437       rtx dreg = operands[1];
5438       if (!REG_P (dreg))
5439         dreg = force_reg (SImode, dreg);
5440       dreg = convert_to_mode (DImode, dreg, false);
5441       emit_insn (gen_floatdidf2 (operands[0], dreg));
5442       DONE;
5443     }
5445   if (!REG_P (operands[1]))
5446     operands[1] = force_reg (SImode, operands[1]);
5447   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5448   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5449   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5450   operands[5] = gen_reg_rtx (DFmode);
5451   operands[6] = gen_reg_rtx (SImode);
5454 (define_insn_and_split "*floatsidf2_internal"
5455   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5456         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5457    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5458    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5459    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5460    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5461    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5462   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5463   "#"
5464   ""
5465   [(pc)]
5467   rtx lowword, highword;
5468   gcc_assert (MEM_P (operands[4]));
5469   highword = adjust_address (operands[4], SImode, 0);
5470   lowword = adjust_address (operands[4], SImode, 4);
5471   if (! WORDS_BIG_ENDIAN)
5472     std::swap (lowword, highword);
5474   emit_insn (gen_xorsi3 (operands[6], operands[1],
5475                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5476   emit_move_insn (lowword, operands[6]);
5477   emit_move_insn (highword, operands[2]);
5478   emit_move_insn (operands[5], operands[4]);
5479   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5480   DONE;
5482   [(set_attr "length" "24")
5483    (set_attr "type" "fp")])
5485 ;; If we don't have a direct conversion to single precision, don't enable this
5486 ;; conversion for 32-bit without fast math, because we don't have the insn to
5487 ;; generate the fixup swizzle to avoid double rounding problems.
5488 (define_expand "floatunssisf2"
5489   [(set (match_operand:SF 0 "gpc_reg_operand")
5490         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5491   "TARGET_HARD_FLOAT
5492    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5493        || (TARGET_FCFID
5494            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5496   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5497     {
5498       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5499       DONE;
5500     }
5501   else
5502     {
5503       rtx dreg = operands[1];
5504       if (!REG_P (dreg))
5505         dreg = force_reg (SImode, dreg);
5506       dreg = convert_to_mode (DImode, dreg, true);
5507       emit_insn (gen_floatdisf2 (operands[0], dreg));
5508       DONE;
5509     }
5512 (define_expand "floatunssidf2"
5513   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5514                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5515               (use (match_dup 2))
5516               (use (match_dup 3))
5517               (clobber (match_dup 4))
5518               (clobber (match_dup 5))])]
5519   "TARGET_HARD_FLOAT"
5521   if (TARGET_LFIWZX && TARGET_FCFID)
5522     {
5523       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5524       DONE;
5525     }
5526   else if (TARGET_FCFID)
5527     {
5528       rtx dreg = operands[1];
5529       if (!REG_P (dreg))
5530         dreg = force_reg (SImode, dreg);
5531       dreg = convert_to_mode (DImode, dreg, true);
5532       emit_insn (gen_floatdidf2 (operands[0], dreg));
5533       DONE;
5534     }
5536   if (!REG_P (operands[1]))
5537     operands[1] = force_reg (SImode, operands[1]);
5538   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5539   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5540   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5541   operands[5] = gen_reg_rtx (DFmode);
5544 (define_insn_and_split "*floatunssidf2_internal"
5545   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5546         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5547    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5548    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5549    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5550    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5551   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5552    && !(TARGET_FCFID && TARGET_POWERPC64)"
5553   "#"
5554   ""
5555   [(pc)]
5557   rtx lowword, highword;
5558   gcc_assert (MEM_P (operands[4]));
5559   highword = adjust_address (operands[4], SImode, 0);
5560   lowword = adjust_address (operands[4], SImode, 4);
5561   if (! WORDS_BIG_ENDIAN)
5562     std::swap (lowword, highword);
5564   emit_move_insn (lowword, operands[1]);
5565   emit_move_insn (highword, operands[2]);
5566   emit_move_insn (operands[5], operands[4]);
5567   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5568   DONE;
5570   [(set_attr "length" "20")
5571    (set_attr "type" "fp")])
5573 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5574 ;; vector registers.  These insns favor doing the sign/zero extension in
5575 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5576 ;; extension and then a direct move.
5578 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5579   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5580                    (float:FP_ISA3
5581                     (match_operand:QHI 1 "input_operand")))
5582               (clobber (match_scratch:DI 2))
5583               (clobber (match_scratch:DI 3))
5584               (clobber (match_scratch:<QHI:MODE> 4))])]
5585   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5587   if (MEM_P (operands[1]))
5588     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5591 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5592   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5593         (float:FP_ISA3
5594          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5595    (clobber (match_scratch:DI 2 "=v,wa,v"))
5596    (clobber (match_scratch:DI 3 "=X,r,X"))
5597    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5598   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5599   "#"
5600   "&& reload_completed"
5601   [(const_int 0)]
5603   rtx result = operands[0];
5604   rtx input = operands[1];
5605   rtx di = operands[2];
5607   if (!MEM_P (input))
5608     {
5609       rtx tmp = operands[3];
5610       if (altivec_register_operand (input, <QHI:MODE>mode))
5611         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5612       else if (GET_CODE (tmp) == SCRATCH)
5613         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5614       else
5615         {
5616           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5617           emit_move_insn (di, tmp);
5618         }
5619     }
5620   else
5621     {
5622       rtx tmp = operands[4];
5623       emit_move_insn (tmp, input);
5624       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5625     }
5627   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5628   DONE;
5630   [(set_attr "isa" "p9v,*,p9v")])
5632 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5633   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5634                    (unsigned_float:FP_ISA3
5635                     (match_operand:QHI 1 "input_operand")))
5636               (clobber (match_scratch:DI 2))
5637               (clobber (match_scratch:DI 3))])]
5638   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5640   if (MEM_P (operands[1]))
5641     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5644 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5645   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5646         (unsigned_float:FP_ISA3
5647          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5648    (clobber (match_scratch:DI 2 "=v,wa,wa"))
5649    (clobber (match_scratch:DI 3 "=X,r,X"))]
5650   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5651   "#"
5652   "&& reload_completed"
5653   [(const_int 0)]
5655   rtx result = operands[0];
5656   rtx input = operands[1];
5657   rtx di = operands[2];
5659   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5660     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5661   else
5662     {
5663       rtx tmp = operands[3];
5664       if (GET_CODE (tmp) == SCRATCH)
5665         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5666       else
5667         {
5668           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5669           emit_move_insn (di, tmp);
5670         }
5671     }
5673   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5674   DONE;
5676   [(set_attr "isa" "p9v,*,p9v")])
5678 (define_expand "fix_trunc<mode>si2"
5679   [(set (match_operand:SI 0 "gpc_reg_operand")
5680         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5681   "TARGET_HARD_FLOAT"
5683   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5684     {
5685       rtx src = force_reg (<MODE>mode, operands[1]);
5687       if (TARGET_STFIWX)
5688         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5689       else
5690         {
5691           rtx tmp = gen_reg_rtx (DImode);
5692           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5693           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5694                                                       tmp, stack));
5695         }
5696       DONE;
5697     }
5700 ; Like the convert to float patterns, this insn must be split before
5701 ; register allocation so that it can allocate the memory slot if it
5702 ; needed
5703 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5704   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5705         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5706    (clobber (match_scratch:DI 2 "=d"))]
5707   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5708    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5709   "#"
5710   ""
5711   [(pc)]
5713   rtx dest = operands[0];
5714   rtx src = operands[1];
5715   rtx tmp = operands[2];
5717   if (GET_CODE (tmp) == SCRATCH)
5718     tmp = gen_reg_rtx (DImode);
5720   emit_insn (gen_fctiwz_<mode> (tmp, src));
5721   if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5722     {
5723       dest = rs6000_force_indexed_or_indirect_mem (dest);
5724       emit_insn (gen_stfiwx (dest, tmp));
5725       DONE;
5726     }
5727   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5728     {
5729       dest = gen_lowpart (DImode, dest);
5730       emit_move_insn (dest, tmp);
5731       DONE;
5732     }
5733   else
5734     {
5735       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5736       emit_insn (gen_stfiwx (stack, tmp));
5737       emit_move_insn (dest, stack);
5738       DONE;
5739     }
5741   [(set_attr "length" "12")
5742    (set_attr "type" "fp")])
5744 (define_insn_and_split "fix_trunc<mode>si2_internal"
5745   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5746         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5747    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5748    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5749   "TARGET_HARD_FLOAT
5750    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5751   "#"
5752   ""
5753   [(pc)]
5755   rtx lowword;
5756   gcc_assert (MEM_P (operands[3]));
5757   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5759   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5760   emit_move_insn (operands[3], operands[2]);
5761   emit_move_insn (operands[0], lowword);
5762   DONE;
5764   [(set_attr "length" "16")
5765    (set_attr "type" "fp")])
5767 (define_expand "fix_trunc<mode>di2"
5768   [(set (match_operand:DI 0 "gpc_reg_operand")
5769         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5770   "TARGET_HARD_FLOAT && TARGET_FCFID"
5771   "")
5773 (define_insn "*fix_trunc<mode>di2_fctidz"
5774   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5775         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5776   "TARGET_HARD_FLOAT && TARGET_FCFID"
5777   "@
5778    fctidz %0,%1
5779    xscvdpsxds %x0,%x1"
5780   [(set_attr "type" "fp")])
5782 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5783 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5784 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5785 ;; values can go in VSX registers.  Keeping the direct move part through
5786 ;; register allocation prevents the register allocator from doing a direct move
5787 ;; of the SImode value to a GPR, and then a store/load.
5788 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5789   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5790         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5791    (clobber (match_scratch:SI 2 "=X,X,wa"))]
5792   "TARGET_DIRECT_MOVE"
5793   "@
5794    fctiw<u>z %0,%1
5795    xscvdp<su>xws %x0,%x1
5796    #"
5797   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5798   [(set (match_dup 2)
5799         (any_fix:SI (match_dup 1)))
5800    (set (match_dup 3)
5801         (match_dup 2))]
5803   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5805   [(set_attr "type" "fp")
5806    (set_attr "length" "4,4,8")
5807    (set_attr "isa" "p9v,p9v,*")])
5809 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5810   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5811         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5812   "TARGET_DIRECT_MOVE"
5813   "@
5814    fctiw<u>z %0,%1
5815    xscvdp<su>xws %x0,%x1"
5816   [(set_attr "type" "fp")])
5818 ;; Keep the convert and store together through register allocation to prevent
5819 ;; the register allocator from getting clever and doing a direct move to a GPR
5820 ;; and then store for reg+offset stores.
5821 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5822   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5823         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5824    (clobber (match_scratch:SI 2 "=wa"))]
5825     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5826   "#"
5827   "&& reload_completed"
5828   [(set (match_dup 2)
5829         (any_fix:SI (match_dup 1)))
5830    (set (match_dup 0)
5831         (match_dup 3))]
5833   operands[3] = (<QHSI:MODE>mode == SImode
5834                  ? operands[2]
5835                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5838 (define_expand "fixuns_trunc<mode>si2"
5839   [(set (match_operand:SI 0 "gpc_reg_operand")
5840         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5841   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5843   if (!TARGET_P8_VECTOR)
5844     {
5845       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5846       DONE;
5847     }
5850 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5851   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5852         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5853    (clobber (match_scratch:DI 2 "=d"))]
5854   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5855    && TARGET_STFIWX && can_create_pseudo_p ()
5856    && !TARGET_P8_VECTOR"
5857   "#"
5858   ""
5859   [(pc)]
5861   rtx dest = operands[0];
5862   rtx src = operands[1];
5863   rtx tmp = operands[2];
5865   if (GET_CODE (tmp) == SCRATCH)
5866     tmp = gen_reg_rtx (DImode);
5868   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5869   if (MEM_P (dest))
5870     {
5871       dest = rs6000_force_indexed_or_indirect_mem (dest);
5872       emit_insn (gen_stfiwx (dest, tmp));
5873       DONE;
5874     }
5875   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5876     {
5877       dest = gen_lowpart (DImode, dest);
5878       emit_move_insn (dest, tmp);
5879       DONE;
5880     }
5881   else
5882     {
5883       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5884       emit_insn (gen_stfiwx (stack, tmp));
5885       emit_move_insn (dest, stack);
5886       DONE;
5887     }
5889   [(set_attr "length" "12")
5890    (set_attr "type" "fp")])
5892 (define_insn "fixuns_trunc<mode>di2"
5893   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5894         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5895   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5896   "@
5897    fctiduz %0,%1
5898    xscvdpuxds %x0,%x1"
5899   [(set_attr "type" "fp")])
5901 (define_insn "rs6000_mtfsb0"
5902   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5903                     UNSPECV_MTFSB0)]
5904   "TARGET_HARD_FLOAT"
5905   "mtfsb0 %0"
5906   [(set_attr "type" "fp")])
5908 (define_insn "rs6000_mtfsb1"
5909   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5910                     UNSPECV_MTFSB1)]
5911   "TARGET_HARD_FLOAT"
5912   "mtfsb1 %0"
5913   [(set_attr "type" "fp")])
5915 (define_insn "rs6000_mffscrn"
5916   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5917         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5918                             UNSPECV_MFFSCRN))]
5919    "TARGET_P9_MISC"
5920    "mffscrn %0,%1"
5921   [(set_attr "type" "fp")])
5923 (define_insn "rs6000_mffscdrn"
5924   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5925    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5926    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5927   "TARGET_P9_MISC"
5928   "mffscdrn %0,%1"
5929   [(set_attr "type" "fp")])
5931 (define_expand "rs6000_set_fpscr_rn"
5932  [(match_operand:DI 0 "reg_or_cint_operand")]
5933   "TARGET_HARD_FLOAT"
5935   rtx tmp_df = gen_reg_rtx (DFmode);
5937   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5938      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5939   if (TARGET_P9_MISC)
5940     {
5941       rtx src_df = force_reg (DImode, operands[0]);
5942       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5943       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5944       DONE;
5945     }
5947   if (CONST_INT_P (operands[0]))
5948     {
5949       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5950         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5951       else
5952         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5954       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5955         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5956       else
5957         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5958     }
5959   else
5960     {
5961       rtx tmp_rn = gen_reg_rtx (DImode);
5962       rtx tmp_di = gen_reg_rtx (DImode);
5964       /* Extract new RN mode from operand.  */
5965       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5967       /* Insert new RN mode into FSCPR.  */
5968       emit_insn (gen_rs6000_mffs (tmp_df));
5969       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5970       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5971       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5973       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5974          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5975          8-bit field[0:7]. Need to set the bit that corresponds to the
5976          value of i that you want [0:7].  */
5977       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5978       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5979     }
5980   DONE;
5983 (define_expand "rs6000_set_fpscr_drn"
5984   [(match_operand:DI 0  "gpc_reg_operand")]
5985   "TARGET_HARD_FLOAT"
5987   rtx tmp_df = gen_reg_rtx (DFmode);
5989   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5990      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5991   if (TARGET_P9_MISC)
5992     {
5993       rtx src_df = gen_reg_rtx (DFmode);
5995       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5996       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5997       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5998     }
5999   else
6000     {
6001       rtx tmp_rn = gen_reg_rtx (DImode);
6002       rtx tmp_di = gen_reg_rtx (DImode);
6004       /* Extract new DRN mode from operand.  */
6005       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6006       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6008       /* Insert new RN mode into FSCPR.  */
6009       emit_insn (gen_rs6000_mffs (tmp_df));
6010       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6011       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
6012       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6014       /* Need to write to field 7.  The fields are [0:15].  The equation to
6015          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6016          i to 0x1 to get field 7 where i selects the field.  */
6017       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6018       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6019     }
6020   DONE;
6023 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6024 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6025 ;; because the first makes it clear that operand 0 is not live
6026 ;; before the instruction.
6027 (define_insn "fctiwz_<mode>"
6028   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6029         (unspec:DI [(fix:SI
6030                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6031                    UNSPEC_FCTIWZ))]
6032   "TARGET_HARD_FLOAT"
6033   "@
6034    fctiwz %0,%1
6035    xscvdpsxws %x0,%x1"
6036   [(set_attr "type" "fp")])
6038 (define_insn "fctiwuz_<mode>"
6039   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6040         (unspec:DI [(unsigned_fix:SI
6041                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6042                    UNSPEC_FCTIWUZ))]
6043   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6044   "@
6045    fctiwuz %0,%1
6046    xscvdpuxws %x0,%x1"
6047   [(set_attr "type" "fp")])
6049 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6050 ;; since the friz instruction does not truncate the value if the floating
6051 ;; point value is < LONG_MIN or > LONG_MAX.
6052 (define_insn "*friz"
6053   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6054         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6055   "TARGET_HARD_FLOAT && TARGET_FPRND
6056    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6057   "@
6058    friz %0,%1
6059    xsrdpiz %x0,%x1"
6060   [(set_attr "type" "fp")])
6062 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6063 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6064 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6065 ;; extend it, store it back on the stack from the GPR, load it back into the
6066 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6067 ;; disable using store and load to sign/zero extend the value.
6068 (define_insn_and_split "*round32<mode>2_fprs"
6069   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6070         (float:SFDF
6071          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6072    (clobber (match_scratch:DI 2 "=d"))
6073    (clobber (match_scratch:DI 3 "=d"))]
6074   "TARGET_HARD_FLOAT
6075    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6076    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6077   "#"
6078   ""
6079   [(pc)]
6081   rtx dest = operands[0];
6082   rtx src = operands[1];
6083   rtx tmp1 = operands[2];
6084   rtx tmp2 = operands[3];
6085   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6087   if (GET_CODE (tmp1) == SCRATCH)
6088     tmp1 = gen_reg_rtx (DImode);
6089   if (GET_CODE (tmp2) == SCRATCH)
6090     tmp2 = gen_reg_rtx (DImode);
6092   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6093   emit_insn (gen_stfiwx (stack, tmp1));
6094   emit_insn (gen_lfiwax (tmp2, stack));
6095   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6096   DONE;
6098   [(set_attr "type" "fpload")
6099    (set_attr "length" "16")])
6101 (define_insn_and_split "*roundu32<mode>2_fprs"
6102   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6103         (unsigned_float:SFDF
6104          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6105    (clobber (match_scratch:DI 2 "=d"))
6106    (clobber (match_scratch:DI 3 "=d"))]
6107   "TARGET_HARD_FLOAT
6108    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6109    && can_create_pseudo_p ()"
6110   "#"
6111   ""
6112   [(pc)]
6114   rtx dest = operands[0];
6115   rtx src = operands[1];
6116   rtx tmp1 = operands[2];
6117   rtx tmp2 = operands[3];
6118   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6120   if (GET_CODE (tmp1) == SCRATCH)
6121     tmp1 = gen_reg_rtx (DImode);
6122   if (GET_CODE (tmp2) == SCRATCH)
6123     tmp2 = gen_reg_rtx (DImode);
6125   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6126   emit_insn (gen_stfiwx (stack, tmp1));
6127   emit_insn (gen_lfiwzx (tmp2, stack));
6128   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6129   DONE;
6131   [(set_attr "type" "fpload")
6132    (set_attr "length" "16")])
6134 ;; No VSX equivalent to fctid
6135 (define_insn "lrint<mode>di2"
6136   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6137         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6138                    UNSPEC_FCTID))]
6139   "TARGET_HARD_FLOAT && TARGET_FPRND"
6140   "fctid %0,%1"
6141   [(set_attr "type" "fp")])
6143 (define_insn "btrunc<mode>2"
6144   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6145         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6146                      UNSPEC_FRIZ))]
6147   "TARGET_HARD_FLOAT && TARGET_FPRND"
6148   "@
6149    friz %0,%1
6150    xsrdpiz %x0,%x1"
6151   [(set_attr "type" "fp")])
6153 (define_insn "ceil<mode>2"
6154   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6155         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6156                      UNSPEC_FRIP))]
6157   "TARGET_HARD_FLOAT && TARGET_FPRND"
6158   "@
6159    frip %0,%1
6160    xsrdpip %x0,%x1"
6161   [(set_attr "type" "fp")])
6163 (define_insn "floor<mode>2"
6164   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6165         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6166                      UNSPEC_FRIM))]
6167   "TARGET_HARD_FLOAT && TARGET_FPRND"
6168   "@
6169    frim %0,%1
6170    xsrdpim %x0,%x1"
6171   [(set_attr "type" "fp")])
6173 ;; No VSX equivalent to frin
6174 (define_insn "round<mode>2"
6175   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6176         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6177                      UNSPEC_FRIN))]
6178   "TARGET_HARD_FLOAT && TARGET_FPRND"
6179   "frin %0,%1"
6180   [(set_attr "type" "fp")])
6182 (define_insn "*xsrdpi<mode>2"
6183   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6184         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6185                      UNSPEC_XSRDPI))]
6186   "TARGET_HARD_FLOAT && TARGET_VSX"
6187   "xsrdpi %x0,%x1"
6188   [(set_attr "type" "fp")])
6190 (define_expand "lround<mode>di2"
6191   [(set (match_dup 2)
6192         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6193                      UNSPEC_XSRDPI))
6194    (set (match_operand:DI 0 "gpc_reg_operand")
6195         (unspec:DI [(match_dup 2)]
6196                    UNSPEC_FCTID))]
6197   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6199   operands[2] = gen_reg_rtx (<MODE>mode);
6202 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6203 (define_insn "stfiwx"
6204   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6205         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6206                    UNSPEC_STFIWX))]
6207   "TARGET_PPC_GFXOPT"
6208   "@
6209    stfiwx %1,%y0
6210    stxsiwx %x1,%y0"
6211   [(set_attr "type" "fpstore")
6212    (set_attr "isa" "*,p8v")])
6214 ;; If we don't have a direct conversion to single precision, don't enable this
6215 ;; conversion for 32-bit without fast math, because we don't have the insn to
6216 ;; generate the fixup swizzle to avoid double rounding problems.
6217 (define_expand "floatsisf2"
6218   [(set (match_operand:SF 0 "gpc_reg_operand")
6219         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6220   "TARGET_HARD_FLOAT
6221    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6222        || (TARGET_FCFID
6223            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6225   if (TARGET_FCFIDS && TARGET_LFIWAX)
6226     {
6227       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6228       DONE;
6229     }
6230   else if (TARGET_FCFID && TARGET_LFIWAX)
6231     {
6232       rtx dfreg = gen_reg_rtx (DFmode);
6233       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6234       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6235       DONE;
6236     }
6237   else
6238     {
6239       rtx dreg = operands[1];
6240       if (!REG_P (dreg))
6241         dreg = force_reg (SImode, dreg);
6242       dreg = convert_to_mode (DImode, dreg, false);
6243       emit_insn (gen_floatdisf2 (operands[0], dreg));
6244       DONE;
6245     }
6248 (define_insn "floatdidf2"
6249   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6250         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6251   "TARGET_FCFID && TARGET_HARD_FLOAT"
6252   "@
6253    fcfid %0,%1
6254    xscvsxddp %x0,%x1"
6255   [(set_attr "type" "fp")])
6257 ; Allow the combiner to merge source memory operands to the conversion so that
6258 ; the optimizer/register allocator doesn't try to load the value too early in a
6259 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6260 ; hit.  We will split after reload to avoid the trip through the GPRs
6262 (define_insn_and_split "*floatdidf2_mem"
6263   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6264         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6265    (clobber (match_scratch:DI 2 "=d,wa"))]
6266   "TARGET_HARD_FLOAT && TARGET_FCFID"
6267   "#"
6268   "&& reload_completed"
6269   [(set (match_dup 2) (match_dup 1))
6270    (set (match_dup 0) (float:DF (match_dup 2)))]
6271   ""
6272   [(set_attr "length" "8")
6273    (set_attr "type" "fpload")])
6275 (define_expand "floatunsdidf2"
6276   [(set (match_operand:DF 0 "gpc_reg_operand")
6277         (unsigned_float:DF
6278          (match_operand:DI 1 "gpc_reg_operand")))]
6279   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6280   "")
6282 (define_insn "*floatunsdidf2_fcfidu"
6283   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6284         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6285   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6286   "@
6287    fcfidu %0,%1
6288    xscvuxddp %x0,%x1"
6289   [(set_attr "type" "fp")])
6291 (define_insn_and_split "*floatunsdidf2_mem"
6292   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6293         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6294    (clobber (match_scratch:DI 2 "=d,wa"))]
6295   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6296   "#"
6297   "&& reload_completed"
6298   [(set (match_dup 2) (match_dup 1))
6299    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6300   ""
6301   [(set_attr "length" "8")
6302    (set_attr "type" "fpload")])
6304 (define_expand "floatdisf2"
6305   [(set (match_operand:SF 0 "gpc_reg_operand")
6306         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6307   "TARGET_FCFID && TARGET_HARD_FLOAT
6308    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6310   if (!TARGET_FCFIDS)
6311     {
6312       rtx val = operands[1];
6313       if (!flag_unsafe_math_optimizations)
6314         {
6315           rtx label = gen_label_rtx ();
6316           val = gen_reg_rtx (DImode);
6317           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6318           emit_label (label);
6319         }
6320       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6321       DONE;
6322     }
6325 (define_insn "floatdisf2_fcfids"
6326   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6327         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6328   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6329   "@
6330    fcfids %0,%1
6331    xscvsxdsp %x0,%x1"
6332   [(set_attr "type" "fp")
6333    (set_attr "isa" "*,p8v")])
6335 (define_insn_and_split "*floatdisf2_mem"
6336   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6337         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6338    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6339   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6340   "#"
6341   "&& reload_completed"
6342   [(pc)]
6344   emit_move_insn (operands[2], operands[1]);
6345   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6346   DONE;
6348   [(set_attr "length" "8")
6349    (set_attr "isa" "*,p8v,p8v")])
6351 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6352 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6353 ;; from double rounding.
6354 ;; Instead of creating a new cpu type for two FP operations, just use fp
6355 (define_insn_and_split "floatdisf2_internal1"
6356   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6357         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6358    (clobber (match_scratch:DF 2 "=d"))]
6359   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6360   "#"
6361   "&& reload_completed"
6362   [(set (match_dup 2)
6363         (float:DF (match_dup 1)))
6364    (set (match_dup 0)
6365         (float_truncate:SF (match_dup 2)))]
6366   ""
6367   [(set_attr "length" "8")
6368    (set_attr "type" "fp")])
6370 ;; Twiddles bits to avoid double rounding.
6371 ;; Bits that might be truncated when converting to DFmode are replaced
6372 ;; by a bit that won't be lost at that stage, but is below the SFmode
6373 ;; rounding position.
6374 (define_expand "floatdisf2_internal2"
6375   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6376                                               (const_int 53)))
6377               (clobber (reg:DI CA_REGNO))])
6378    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6379                                         (const_int 2047)))
6380    (set (match_dup 3) (plus:DI (match_dup 3)
6381                                (const_int 1)))
6382    (set (match_dup 0) (plus:DI (match_dup 0)
6383                                (const_int 2047)))
6384    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6385                                      (const_int 2)))
6386    (set (match_dup 0) (ior:DI (match_dup 0)
6387                               (match_dup 1)))
6388    (set (match_dup 0) (and:DI (match_dup 0)
6389                               (const_int -2048)))
6390    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6391                            (label_ref (match_operand:DI 2 ""))
6392                            (pc)))
6393    (set (match_dup 0) (match_dup 1))]
6394   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6396   operands[3] = gen_reg_rtx (DImode);
6397   operands[4] = gen_reg_rtx (CCUNSmode);
6400 (define_expand "floatunsdisf2"
6401   [(set (match_operand:SF 0 "gpc_reg_operand")
6402         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6403   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6404   "")
6406 (define_insn "floatunsdisf2_fcfidus"
6407   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6408         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6409   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6410   "@
6411    fcfidus %0,%1
6412    xscvuxdsp %x0,%x1"
6413   [(set_attr "type" "fp")
6414    (set_attr "isa" "*,p8v")])
6416 (define_insn_and_split "*floatunsdisf2_mem"
6417   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6418         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6419    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6420   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6421   "#"
6422   "&& reload_completed"
6423   [(pc)]
6425   emit_move_insn (operands[2], operands[1]);
6426   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6427   DONE;
6429   [(set_attr "type" "fpload")
6430    (set_attr "length" "8")
6431    (set_attr "isa" "*,p8v,p8v")])
6433 ;; Define the TImode operations that can be done in a small number
6434 ;; of instructions.  The & constraints are to prevent the register
6435 ;; allocator from allocating registers that overlap with the inputs
6436 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6437 ;; also allow for the output being the same as one of the inputs.
6439 (define_expand "addti3"
6440   [(set (match_operand:TI 0 "gpc_reg_operand")
6441         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6442                  (match_operand:TI 2 "reg_or_short_operand")))]
6443   "TARGET_64BIT"
6445   rtx lo0 = gen_lowpart (DImode, operands[0]);
6446   rtx lo1 = gen_lowpart (DImode, operands[1]);
6447   rtx lo2 = gen_lowpart (DImode, operands[2]);
6448   rtx hi0 = gen_highpart (DImode, operands[0]);
6449   rtx hi1 = gen_highpart (DImode, operands[1]);
6450   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6452   if (!reg_or_short_operand (lo2, DImode))
6453     lo2 = force_reg (DImode, lo2);
6454   if (!adde_operand (hi2, DImode))
6455     hi2 = force_reg (DImode, hi2);
6457   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6458   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6459   DONE;
6462 (define_expand "subti3"
6463   [(set (match_operand:TI 0 "gpc_reg_operand")
6464         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6465                   (match_operand:TI 2 "gpc_reg_operand")))]
6466   "TARGET_64BIT"
6468   rtx lo0 = gen_lowpart (DImode, operands[0]);
6469   rtx lo1 = gen_lowpart (DImode, operands[1]);
6470   rtx lo2 = gen_lowpart (DImode, operands[2]);
6471   rtx hi0 = gen_highpart (DImode, operands[0]);
6472   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6473   rtx hi2 = gen_highpart (DImode, operands[2]);
6475   if (!reg_or_short_operand (lo1, DImode))
6476     lo1 = force_reg (DImode, lo1);
6477   if (!adde_operand (hi1, DImode))
6478     hi1 = force_reg (DImode, hi1);
6480   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6481   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6482   DONE;
6485 ;; 128-bit logical operations expanders
6487 (define_expand "and<mode>3"
6488   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6489         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6490                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6491   ""
6492   "")
6494 (define_expand "ior<mode>3"
6495   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6496         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6497                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6498   ""
6499   "")
6501 (define_expand "xor<mode>3"
6502   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6503         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6504                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6505   ""
6506   "")
6508 (define_expand "nor<mode>3"
6509   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6510         (and:BOOL_128
6511          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6512          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6513   ""
6514   "")
6516 (define_expand "andc<mode>3"
6517   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6518         (and:BOOL_128
6519          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6520          (match_operand:BOOL_128 1 "vlogical_operand")))]
6521   ""
6522   "")
6524 ;; Power8 vector logical instructions.
6525 (define_expand "eqv<mode>3"
6526   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6527         (not:BOOL_128
6528          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6529                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6530   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6531   "")
6533 ;; Rewrite nand into canonical form
6534 (define_expand "nand<mode>3"
6535   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6536         (ior:BOOL_128
6537          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6538          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6539   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6540   "")
6542 ;; The canonical form is to have the negated element first, so we need to
6543 ;; reverse arguments.
6544 (define_expand "orc<mode>3"
6545   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6546         (ior:BOOL_128
6547          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6548          (match_operand:BOOL_128 1 "vlogical_operand")))]
6549   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6550   "")
6552 ;; 128-bit logical operations insns and split operations
6553 (define_insn_and_split "*and<mode>3_internal"
6554   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6555         (and:BOOL_128
6556          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6557          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6558   ""
6560   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6561     return "xxland %x0,%x1,%x2";
6563   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6564     return "vand %0,%1,%2";
6566   return "#";
6568   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6569   [(const_int 0)]
6571   rs6000_split_logical (operands, AND, false, false, false);
6572   DONE;
6574   [(set (attr "type")
6575       (if_then_else
6576         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6577         (const_string "veclogical")
6578         (const_string "integer")))
6579    (set (attr "length")
6580       (if_then_else
6581         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6582         (const_string "4")
6583         (if_then_else
6584          (match_test "TARGET_POWERPC64")
6585          (const_string "8")
6586          (const_string "16"))))])
6588 ;; 128-bit IOR/XOR
6589 (define_insn_and_split "*bool<mode>3_internal"
6590   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6591         (match_operator:BOOL_128 3 "boolean_or_operator"
6592          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6593           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6594   ""
6596   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6597     return "xxl%q3 %x0,%x1,%x2";
6599   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6600     return "v%q3 %0,%1,%2";
6602   return "#";
6604   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6605   [(const_int 0)]
6607   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6608   DONE;
6610   [(set (attr "type")
6611       (if_then_else
6612         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6613         (const_string "veclogical")
6614         (const_string "integer")))
6615    (set (attr "length")
6616       (if_then_else
6617         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6618         (const_string "4")
6619         (if_then_else
6620          (match_test "TARGET_POWERPC64")
6621          (const_string "8")
6622          (const_string "16"))))])
6624 ;; 128-bit ANDC/ORC
6625 (define_insn_and_split "*boolc<mode>3_internal1"
6626   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6627         (match_operator:BOOL_128 3 "boolean_operator"
6628          [(not:BOOL_128
6629            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6630           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6631   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6633   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6634     return "xxl%q3 %x0,%x1,%x2";
6636   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6637     return "v%q3 %0,%1,%2";
6639   return "#";
6641   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6642    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6643   [(const_int 0)]
6645   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6646   DONE;
6648   [(set (attr "type")
6649       (if_then_else
6650         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6651         (const_string "veclogical")
6652         (const_string "integer")))
6653    (set (attr "length")
6654       (if_then_else
6655         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6656         (const_string "4")
6657         (if_then_else
6658          (match_test "TARGET_POWERPC64")
6659          (const_string "8")
6660          (const_string "16"))))])
6662 (define_insn_and_split "*boolc<mode>3_internal2"
6663   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6664         (match_operator:TI2 3 "boolean_operator"
6665          [(not:TI2
6666            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6667           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6668   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6669   "#"
6670   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6671   [(const_int 0)]
6673   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6674   DONE;
6676   [(set_attr "type" "integer")
6677    (set (attr "length")
6678         (if_then_else
6679          (match_test "TARGET_POWERPC64")
6680          (const_string "8")
6681          (const_string "16")))])
6683 ;; 128-bit NAND/NOR
6684 (define_insn_and_split "*boolcc<mode>3_internal1"
6685   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6686         (match_operator:BOOL_128 3 "boolean_operator"
6687          [(not:BOOL_128
6688            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6689           (not:BOOL_128
6690            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6691   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6693   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6694     return "xxl%q3 %x0,%x1,%x2";
6696   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6697     return "v%q3 %0,%1,%2";
6699   return "#";
6701   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6702    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6703   [(const_int 0)]
6705   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6706   DONE;
6708   [(set (attr "type")
6709       (if_then_else
6710         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6711         (const_string "veclogical")
6712         (const_string "integer")))
6713    (set (attr "length")
6714       (if_then_else
6715         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6716         (const_string "4")
6717         (if_then_else
6718          (match_test "TARGET_POWERPC64")
6719          (const_string "8")
6720          (const_string "16"))))])
6722 (define_insn_and_split "*boolcc<mode>3_internal2"
6723   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6724         (match_operator:TI2 3 "boolean_operator"
6725          [(not:TI2
6726            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6727           (not:TI2
6728            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6729   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6730   "#"
6731   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6732   [(const_int 0)]
6734   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6735   DONE;
6737   [(set_attr "type" "integer")
6738    (set (attr "length")
6739         (if_then_else
6740          (match_test "TARGET_POWERPC64")
6741          (const_string "8")
6742          (const_string "16")))])
6745 ;; 128-bit EQV
6746 (define_insn_and_split "*eqv<mode>3_internal1"
6747   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6748         (not:BOOL_128
6749          (xor:BOOL_128
6750           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6751           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6752   "TARGET_P8_VECTOR"
6754   if (vsx_register_operand (operands[0], <MODE>mode))
6755     return "xxleqv %x0,%x1,%x2";
6757   return "#";
6759   "TARGET_P8_VECTOR && reload_completed
6760    && int_reg_operand (operands[0], <MODE>mode)"
6761   [(const_int 0)]
6763   rs6000_split_logical (operands, XOR, true, false, false);
6764   DONE;
6766   [(set (attr "type")
6767       (if_then_else
6768         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6769         (const_string "veclogical")
6770         (const_string "integer")))
6771    (set (attr "length")
6772       (if_then_else
6773         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6774         (const_string "4")
6775         (if_then_else
6776          (match_test "TARGET_POWERPC64")
6777          (const_string "8")
6778          (const_string "16"))))])
6780 (define_insn_and_split "*eqv<mode>3_internal2"
6781   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6782         (not:TI2
6783          (xor:TI2
6784           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6785           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6786   "!TARGET_P8_VECTOR"
6787   "#"
6788   "reload_completed && !TARGET_P8_VECTOR"
6789   [(const_int 0)]
6791   rs6000_split_logical (operands, XOR, true, false, false);
6792   DONE;
6794   [(set_attr "type" "integer")
6795    (set (attr "length")
6796         (if_then_else
6797          (match_test "TARGET_POWERPC64")
6798          (const_string "8")
6799          (const_string "16")))])
6801 ;; 128-bit one's complement
6802 (define_insn_and_split "one_cmpl<mode>2"
6803   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6804         (not:BOOL_128
6805           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6806   ""
6808   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6809     return "xxlnor %x0,%x1,%x1";
6811   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6812     return "vnor %0,%1,%1";
6814   return "#";
6816   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6817   [(const_int 0)]
6819   rs6000_split_logical (operands, NOT, false, false, false);
6820   DONE;
6822   [(set (attr "type")
6823       (if_then_else
6824         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6825         (const_string "veclogical")
6826         (const_string "integer")))
6827    (set (attr "length")
6828       (if_then_else
6829         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6830         (const_string "4")
6831         (if_then_else
6832          (match_test "TARGET_POWERPC64")
6833          (const_string "8")
6834          (const_string "16"))))])
6837 ;; Now define ways of moving data around.
6839 ;; Set up a register with a value from the GOT table
6841 (define_expand "movsi_got"
6842   [(set (match_operand:SI 0 "gpc_reg_operand")
6843         (unspec:SI [(match_operand:SI 1 "got_operand")
6844                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6845   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6847   if (GET_CODE (operands[1]) == CONST)
6848     {
6849       rtx offset = const0_rtx;
6850       HOST_WIDE_INT value;
6852       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6853       value = INTVAL (offset);
6854       if (value != 0)
6855         {
6856           rtx tmp = (!can_create_pseudo_p ()
6857                      ? operands[0]
6858                      : gen_reg_rtx (Pmode));
6859           emit_insn (gen_movsi_got (tmp, operands[1]));
6860           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6861           DONE;
6862         }
6863     }
6865   operands[2] = rs6000_got_register (operands[1]);
6868 (define_insn "*movsi_got_internal"
6869   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6870         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6871                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6872                    UNSPEC_MOVSI_GOT))]
6873   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6874   "lwz %0,%a1@got(%2)"
6875   [(set_attr "type" "load")])
6877 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6878 ;; didn't get allocated to a hard register.
6879 (define_split
6880   [(set (match_operand:SI 0 "gpc_reg_operand")
6881         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6882                     (match_operand:SI 2 "memory_operand")]
6883                    UNSPEC_MOVSI_GOT))]
6884   "DEFAULT_ABI == ABI_V4
6885     && flag_pic == 1
6886     && reload_completed"
6887   [(set (match_dup 0) (match_dup 2))
6888    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6889                                  UNSPEC_MOVSI_GOT))]
6890   "")
6892 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6893 ;;              STW          STFIWX       STXSIWX      LI           LIS
6894 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6895 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6896 ;;              MF%1         MT%0         NOP
6897 (define_insn "*movsi_internal1"
6898   [(set (match_operand:SI 0 "nonimmediate_operand"
6899                 "=r,         r,           r,           d,           v,
6900                  m,          Z,           Z,           r,           r,
6901                  r,          wa,          wa,          wa,          v,
6902                  wa,         v,           v,           wa,          r,
6903                  r,          *h,          *h")
6904         (match_operand:SI 1 "input_operand"
6905                 "r,          U,           m,           Z,           Z,
6906                  r,          d,           v,           I,           L,
6907                  n,          wa,          O,           wM,          wB,
6908                  O,          wM,          wS,          r,           wa,
6909                  *h,         r,           0"))]
6910   "gpc_reg_operand (operands[0], SImode)
6911    || gpc_reg_operand (operands[1], SImode)"
6912   "@
6913    mr %0,%1
6914    la %0,%a1
6915    lwz%U1%X1 %0,%1
6916    lfiwzx %0,%y1
6917    lxsiwzx %x0,%y1
6918    stw%U0%X0 %1,%0
6919    stfiwx %1,%y0
6920    stxsiwx %x1,%y0
6921    li %0,%1
6922    lis %0,%v1
6923    #
6924    xxlor %x0,%x1,%x1
6925    xxspltib %x0,0
6926    xxspltib %x0,255
6927    vspltisw %0,%1
6928    xxlxor %x0,%x0,%x0
6929    xxlorc %x0,%x0,%x0
6930    #
6931    mtvsrwz %x0,%1
6932    mfvsrwz %0,%x1
6933    mf%1 %0
6934    mt%0 %1
6935    nop"
6936   [(set_attr "type"
6937                 "*,          *,           load,        fpload,      fpload,
6938                  store,      fpstore,     fpstore,     *,           *,
6939                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6940                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6941                  *,          *,           *")
6942    (set_attr "length"
6943                 "*,          *,           *,           *,           *,
6944                  *,          *,           *,           *,           *,
6945                  8,          *,           *,           *,           *,
6946                  *,          *,           8,           *,           *,
6947                  *,          *,           *")
6948    (set_attr "isa"
6949                 "*,          *,           *,           p8v,         p8v,
6950                  *,          p8v,         p8v,         *,           *,
6951                  *,          p8v,         p9v,         p9v,         p8v,
6952                  p9v,        p8v,         p9v,         p8v,         p8v,
6953                  *,          *,           *")])
6955 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6956 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6958 ;; Because SF values are actually stored as DF values within the vector
6959 ;; registers, we need to convert the value to the vector SF format when
6960 ;; we need to use the bits in a union or similar cases.  We only need
6961 ;; to do this transformation when the value is a vector register.  Loads,
6962 ;; stores, and transfers within GPRs are assumed to be safe.
6964 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6965 ;; no alternatives, because the call is created as part of secondary_reload,
6966 ;; and operand #2's register class is used to allocate the temporary register.
6967 ;; This function is called before reload, and it creates the temporary as
6968 ;; needed.
6970 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6971 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6972 ;;              MTVSRWZ
6974 (define_insn_and_split "movsi_from_sf"
6975   [(set (match_operand:SI 0 "nonimmediate_operand"
6976                 "=r,         r,           ?*d,         ?*v,      m,
6977                  m,          wY,          Z,           r,        ?*wa,
6978                  wa")
6979         (unspec:SI [(match_operand:SF 1 "input_operand"
6980                 "r,          m,           Z,           Z,        r,
6981                  f,          v,           wa,          wa,       wa,
6982                  r")]
6983                     UNSPEC_SI_FROM_SF))
6984    (clobber (match_scratch:V4SF 2
6985                 "=X,         X,           X,           X,        X,
6986                  X,          X,           X,           wa,       X,
6987                  X"))]
6988   "TARGET_NO_SF_SUBREG
6989    && (register_operand (operands[0], SImode)
6990        || register_operand (operands[1], SFmode))"
6991   "@
6992    mr %0,%1
6993    lwz%U1%X1 %0,%1
6994    lfiwzx %0,%y1
6995    lxsiwzx %x0,%y1
6996    stw%U0%X0 %1,%0
6997    stfs%U0%X0 %1,%0
6998    stxssp %1,%0
6999    stxsspx %x1,%y0
7000    #
7001    xscvdpspn %x0,%x1
7002    mtvsrwz %x0,%1"
7003   "&& reload_completed
7004    && int_reg_operand (operands[0], SImode)
7005    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7006   [(const_int 0)]
7008   rtx op0 = operands[0];
7009   rtx op1 = operands[1];
7010   rtx op2 = operands[2];
7011   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7012   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7014   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7015   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7016   DONE;
7018   [(set_attr "type"
7019                 "*,          load,        fpload,      fpload,   store,
7020                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
7021                  mffgpr")
7022    (set_attr "length"
7023                 "*,          *,           *,           *,        *,
7024                  *,          *,           *,           8,        *,
7025                  *")
7026    (set_attr "isa"
7027                 "*,          *,           p8v,         p8v,      *,
7028                  *,          p9v,         p8v,         p8v,      p8v,
7029                  p8v")])
7031 ;; movsi_from_sf with zero extension
7033 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7034 ;;              VSX->VSX     MTVSRWZ
7036 (define_insn_and_split "*movdi_from_sf_zero_ext"
7037   [(set (match_operand:DI 0 "gpc_reg_operand"
7038                 "=r,         r,           ?*d,         ?*v,      r,
7039                  ?v,         wa")
7040         (zero_extend:DI
7041          (unspec:SI [(match_operand:SF 1 "input_operand"
7042                 "r,          m,           Z,           Z,        wa,
7043                  wa,         r")]
7044                     UNSPEC_SI_FROM_SF)))
7045    (clobber (match_scratch:V4SF 2
7046                 "=X,         X,           X,           X,        wa,
7047                  wa,         X"))]
7048   "TARGET_DIRECT_MOVE_64BIT
7049    && (register_operand (operands[0], DImode)
7050        || register_operand (operands[1], SImode))"
7051   "@
7052    rldicl %0,%1,0,32
7053    lwz%U1%X1 %0,%1
7054    lfiwzx %0,%y1
7055    lxsiwzx %x0,%y1
7056    #
7057    #
7058    mtvsrwz %x0,%1"
7059   "&& reload_completed
7060    && register_operand (operands[0], DImode)
7061    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7062   [(const_int 0)]
7064   rtx op0 = operands[0];
7065   rtx op1 = operands[1];
7066   rtx op2 = operands[2];
7067   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7069   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7070   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7071   DONE;
7073   [(set_attr "type"
7074                 "*,          load,        fpload,      fpload,   two,
7075                  two,        mffgpr")
7076    (set_attr "length"
7077                 "*,          *,           *,           *,        8,
7078                  8,          *")
7079    (set_attr "isa"
7080                 "*,          *,           p8v,         p8v,      p8v,
7081                  p9v,        p8v")])
7083 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7084 ;; moving it to SImode.  We cannot do a SFmode store without having to do the
7085 ;; conversion explicitly since that doesn't work in most cases if the input
7086 ;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7087 ;; former handles cases where the input will not fit in a SFmode, and the
7088 ;; latter assumes the value has already been rounded.
7089 (define_insn "*movsi_from_df"
7090   [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7091         (unspec:SI [(float_truncate:SF
7092                      (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7093                     UNSPEC_SI_FROM_SF))]
7094   "TARGET_NO_SF_SUBREG"
7095   "xscvdpsp %x0,%x1"
7096   [(set_attr "type" "fp")])
7098 ;; Split a load of a large constant into the appropriate two-insn
7099 ;; sequence.
7101 (define_split
7102   [(set (match_operand:SI 0 "gpc_reg_operand")
7103         (match_operand:SI 1 "const_int_operand"))]
7104   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7105    && (INTVAL (operands[1]) & 0xffff) != 0"
7106   [(set (match_dup 0)
7107         (match_dup 2))
7108    (set (match_dup 0)
7109         (ior:SI (match_dup 0)
7110                 (match_dup 3)))]
7112   if (rs6000_emit_set_const (operands[0], operands[1]))
7113     DONE;
7114   else
7115     FAIL;
7118 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7119 (define_split
7120   [(set (match_operand:DI 0 "altivec_register_operand")
7121         (match_operand:DI 1 "xxspltib_constant_split"))]
7122   "TARGET_P9_VECTOR && reload_completed"
7123   [(const_int 0)]
7125   rtx op0 = operands[0];
7126   rtx op1 = operands[1];
7127   int r = REGNO (op0);
7128   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7130   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7131   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7132   DONE;
7135 (define_insn "*mov<mode>_internal2"
7136   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7137         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7138                     (const_int 0)))
7139    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7140   ""
7141   "@
7142    cmp<wd>i %2,%0,0
7143    mr. %0,%1
7144    #"
7145   [(set_attr "type" "cmp,logical,cmp")
7146    (set_attr "dot" "yes")
7147    (set_attr "length" "4,4,8")])
7149 (define_split
7150   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7151         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7152                     (const_int 0)))
7153    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7154   "reload_completed"
7155   [(set (match_dup 0) (match_dup 1))
7156    (set (match_dup 2)
7157         (compare:CC (match_dup 0)
7158                     (const_int 0)))]
7159   "")
7161 (define_expand "mov<mode>"
7162   [(set (match_operand:INT 0 "general_operand")
7163         (match_operand:INT 1 "any_operand"))]
7164   ""
7166   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7167   DONE;
7170 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7171 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7172 ;;              MTVSRWZ     MF%1       MT%1       NOP
7173 (define_insn "*mov<mode>_internal"
7174   [(set (match_operand:QHI 0 "nonimmediate_operand"
7175                 "=r,        r,         wa,        m,         Z,         r,
7176                  wa,        wa,        wa,        v,         ?v,        r,
7177                  wa,        r,         *c*l,      *h")
7178         (match_operand:QHI 1 "input_operand"
7179                 "r,         m,         Z,         r,         wa,        i,
7180                  wa,        O,         wM,        wB,        wS,        wa,
7181                  r,         *h,        r,         0"))]
7182   "gpc_reg_operand (operands[0], <MODE>mode)
7183    || gpc_reg_operand (operands[1], <MODE>mode)"
7184   "@
7185    mr %0,%1
7186    l<wd>z%U1%X1 %0,%1
7187    lxsi<wd>zx %x0,%y1
7188    st<wd>%U0%X0 %1,%0
7189    stxsi<wd>x %x1,%y0
7190    li %0,%1
7191    xxlor %x0,%x1,%x1
7192    xxspltib %x0,0
7193    xxspltib %x0,255
7194    vspltis<wd> %0,%1
7195    #
7196    mfvsrwz %0,%x1
7197    mtvsrwz %x0,%1
7198    mf%1 %0
7199    mt%0 %1
7200    nop"
7201   [(set_attr "type"
7202                 "*,         load,      fpload,    store,     fpstore,   *,
7203                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7204                  mffgpr,    mfjmpr,    mtjmpr,    *")
7205    (set_attr "length"
7206                 "*,         *,         *,         *,         *,         *,
7207                  *,         *,         *,         *,         8,         *,
7208                  *,         *,         *,         *")
7209    (set_attr "isa"
7210                 "*,         *,         p9v,       *,         p9v,       *,
7211                  p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7212                  p9v,       *,         *,         *")])
7215 ;; Here is how to move condition codes around.  When we store CC data in
7216 ;; an integer register or memory, we store just the high-order 4 bits.
7217 ;; This lets us not shift in the most common case of CR0.
7218 (define_expand "movcc"
7219   [(set (match_operand:CC 0 "nonimmediate_operand")
7220         (match_operand:CC 1 "nonimmediate_operand"))]
7221   ""
7222   "")
7224 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7226 (define_insn "*movcc_<mode>"
7227   [(set (match_operand:CC_any 0 "nonimmediate_operand"
7228                                 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7229         (match_operand:CC_any 1 "general_operand"
7230                                 " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7231   "register_operand (operands[0], <MODE>mode)
7232    || register_operand (operands[1], <MODE>mode)"
7233   "@
7234    mcrf %0,%1
7235    mtcrf 128,%1
7236    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7237    crxor %0,%0,%0
7238    mfcr %0%Q1
7239    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7240    mr %0,%1
7241    li %0,%1
7242    mf%1 %0
7243    mt%0 %1
7244    lwz%U1%X1 %0,%1
7245    stw%U0%X0 %1,%0"
7246   [(set_attr_alternative "type"
7247      [(const_string "cr_logical")
7248       (const_string "mtcr")
7249       (const_string "mtcr")
7250       (const_string "cr_logical")
7251       (if_then_else (match_test "TARGET_MFCRF")
7252                     (const_string "mfcrf") (const_string "mfcr"))
7253       (if_then_else (match_test "TARGET_MFCRF")
7254                     (const_string "mfcrf") (const_string "mfcr"))
7255       (const_string "integer")
7256       (const_string "integer")
7257       (const_string "mfjmpr")
7258       (const_string "mtjmpr")
7259       (const_string "load")
7260       (const_string "store")])
7261    (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7263 ;; For floating-point, we normally deal with the floating-point registers
7264 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7265 ;; can produce floating-point values in fixed-point registers.  Unless the
7266 ;; value is a simple constant or already in memory, we deal with this by
7267 ;; allocating memory and copying the value explicitly via that memory location.
7269 ;; Move 32-bit binary/decimal floating point
7270 (define_expand "mov<mode>"
7271   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7272         (match_operand:FMOVE32 1 "any_operand"))]
7273   "<fmove_ok>"
7275   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7276   DONE;
7279 (define_split
7280   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7281         (match_operand:FMOVE32 1 "const_double_operand"))]
7282   "reload_completed
7283    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7284        || (SUBREG_P (operands[0])
7285            && REG_P (SUBREG_REG (operands[0]))
7286            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7287   [(set (match_dup 2) (match_dup 3))]
7289   long l;
7291   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7293   if (! TARGET_POWERPC64)
7294     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7295   else
7296     operands[2] = gen_lowpart (SImode, operands[0]);
7298   operands[3] = gen_int_mode (l, SImode);
7301 ;; Originally, we tried to keep movsf and movsd common, but the differences
7302 ;; addressing was making it rather difficult to hide with mode attributes.  In
7303 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7304 ;; before the VSX stores meant that the register allocator would tend to do a
7305 ;; direct move to the GPR (which involves conversion from scalar to
7306 ;; vector/memory formats) to save values in the traditional Altivec registers,
7307 ;; while SDmode had problems on power6 if the GPR store was not first due to
7308 ;; the power6 not having an integer store operation.
7310 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7311 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7312 ;;      MR           MT<x>      MF<x>       NOP
7314 (define_insn "movsf_hardfloat"
7315   [(set (match_operand:SF 0 "nonimmediate_operand"
7316          "=!r,       f,         v,          wa,        m,         wY,
7317           Z,         m,         wa,         !r,        f,         wa,
7318           !r,        *c*l,      !r,         *h")
7319         (match_operand:SF 1 "input_operand"
7320          "m,         m,         wY,         Z,         f,         v,
7321           wa,        r,         j,          j,         f,         wa,
7322           r,         r,         *h,         0"))]
7323   "(register_operand (operands[0], SFmode)
7324    || register_operand (operands[1], SFmode))
7325    && TARGET_HARD_FLOAT
7326    && (TARGET_ALLOW_SF_SUBREG
7327        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7328   "@
7329    lwz%U1%X1 %0,%1
7330    lfs%U1%X1 %0,%1
7331    lxssp %0,%1
7332    lxsspx %x0,%y1
7333    stfs%U0%X0 %1,%0
7334    stxssp %1,%0
7335    stxsspx %x1,%y0
7336    stw%U0%X0 %1,%0
7337    xxlxor %x0,%x0,%x0
7338    li %0,0
7339    fmr %0,%1
7340    xscpsgndp %x0,%x1,%x1
7341    mr %0,%1
7342    mt%0 %1
7343    mf%1 %0
7344    nop"
7345   [(set_attr "type"
7346         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7347          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7348          *,          mtjmpr,    mfjmpr,     *")
7349    (set_attr "isa"
7350         "*,          *,         p9v,        p8v,       *,         p9v,
7351          p8v,        *,         *,          *,         *,         *,
7352          *,          *,         *,          *")])
7354 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7355 ;;      FMR          MR         MT%0       MF%1       NOP
7356 (define_insn "movsd_hardfloat"
7357   [(set (match_operand:SD 0 "nonimmediate_operand"
7358          "=!r,       d,         m,         Z,         ?d,        ?r,
7359           f,         !r,        *c*l,      !r,        *h")
7360         (match_operand:SD 1 "input_operand"
7361          "m,         Z,         r,         wx,        r,         d,
7362           f,         r,         r,         *h,        0"))]
7363   "(register_operand (operands[0], SDmode)
7364    || register_operand (operands[1], SDmode))
7365    && TARGET_HARD_FLOAT"
7366   "@
7367    lwz%U1%X1 %0,%1
7368    lfiwzx %0,%y1
7369    stw%U0%X0 %1,%0
7370    stfiwx %1,%y0
7371    mtvsrwz %x0,%1
7372    mfvsrwz %0,%x1
7373    fmr %0,%1
7374    mr %0,%1
7375    mt%0 %1
7376    mf%1 %0
7377    nop"
7378   [(set_attr "type"
7379         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7380          fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7381    (set_attr "isa"
7382         "*,          p7,        *,         *,         p8v,       p8v,
7383          *,          *,         *,         *,         *")])
7385 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7386 ;;      LIS          G-const.   F/n-const  NOP
7387 (define_insn "*mov<mode>_softfloat"
7388   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7389         "=r,         *c*l,      r,         r,         m,         r,
7390           r,         r,         r,         *h")
7392         (match_operand:FMOVE32 1 "input_operand"
7393          "r,         r,         *h,        m,         r,         I,
7394           L,         G,         Fn,        0"))]
7396   "(gpc_reg_operand (operands[0], <MODE>mode)
7397    || gpc_reg_operand (operands[1], <MODE>mode))
7398    && TARGET_SOFT_FLOAT"
7399   "@
7400    mr %0,%1
7401    mt%0 %1
7402    mf%1 %0
7403    lwz%U1%X1 %0,%1
7404    stw%U0%X0 %1,%0
7405    li %0,%1
7406    lis %0,%v1
7407    #
7408    #
7409    nop"
7410   [(set_attr "type"
7411         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7412          *,          *,         *,         *")
7414    (set_attr "length"
7415         "*,          *,         *,         *,         *,         *,
7416          *,          *,         8,         *")])
7418 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7419 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7421 ;; Because SF values are actually stored as DF values within the vector
7422 ;; registers, we need to convert the value to the vector SF format when
7423 ;; we need to use the bits in a union or similar cases.  We only need
7424 ;; to do this transformation when the value is a vector register.  Loads,
7425 ;; stores, and transfers within GPRs are assumed to be safe.
7427 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7428 ;; no alternatives, because the call is created as part of secondary_reload,
7429 ;; and operand #2's register class is used to allocate the temporary register.
7430 ;; This function is called before reload, and it creates the temporary as
7431 ;; needed.
7433 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7434 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7435 (define_insn_and_split "movsf_from_si"
7436   [(set (match_operand:SF 0 "nonimmediate_operand"
7437             "=!r,       f,         v,         wa,        m,         Z,
7438              Z,         wa,        ?r,        !r")
7439         (unspec:SF [(match_operand:SI 1 "input_operand" 
7440             "m,         m,         wY,        Z,         r,         f,
7441              wa,        r,         wa,        r")]
7442                    UNSPEC_SF_FROM_SI))
7443    (clobber (match_scratch:DI 2
7444             "=X,        X,         X,         X,         X,         X,
7445              X,         r,         X,         X"))]
7446   "TARGET_NO_SF_SUBREG
7447    && (register_operand (operands[0], SFmode)
7448        || register_operand (operands[1], SImode))"
7449   "@
7450    lwz%U1%X1 %0,%1
7451    lfs%U1%X1 %0,%1
7452    lxssp %0,%1
7453    lxsspx %x0,%y1
7454    stw%U0%X0 %1,%0
7455    stfiwx %1,%y0
7456    stxsiwx %x1,%y0
7457    #
7458    mfvsrwz %0,%x1
7459    mr %0,%1"
7461   "&& reload_completed
7462    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7463    && int_reg_operand_not_pseudo (operands[1], SImode)"
7464   [(const_int 0)]
7466   rtx op0 = operands[0];
7467   rtx op1 = operands[1];
7468   rtx op2 = operands[2];
7469   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7471   /* Move SF value to upper 32-bits for xscvspdpn.  */
7472   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7473   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7474   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7475   DONE;
7477   [(set_attr "length"
7478             "*,          *,         *,         *,         *,         *,
7479              *,          12,        *,         *")
7480    (set_attr "type"
7481             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7482              fpstore,    vecfloat,  mffgpr,    *")
7483    (set_attr "isa"
7484             "*,          *,         p9v,       p8v,       *,         *,
7485              p8v,        p8v,       p8v,       *")])
7488 ;; Move 64-bit binary/decimal floating point
7489 (define_expand "mov<mode>"
7490   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7491         (match_operand:FMOVE64 1 "any_operand"))]
7492   ""
7494   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7495   DONE;
7498 (define_split
7499   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7500         (match_operand:FMOVE64 1 "const_int_operand"))]
7501   "! TARGET_POWERPC64 && reload_completed
7502    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7503        || (SUBREG_P (operands[0])
7504            && REG_P (SUBREG_REG (operands[0]))
7505            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7506   [(set (match_dup 2) (match_dup 4))
7507    (set (match_dup 3) (match_dup 1))]
7509   int endian = (WORDS_BIG_ENDIAN == 0);
7510   HOST_WIDE_INT value = INTVAL (operands[1]);
7512   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7513   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7514   operands[4] = GEN_INT (value >> 32);
7515   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7518 (define_split
7519   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7520         (match_operand:FMOVE64 1 "const_double_operand"))]
7521   "! TARGET_POWERPC64 && reload_completed
7522    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7523        || (SUBREG_P (operands[0])
7524            && REG_P (SUBREG_REG (operands[0]))
7525            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7526   [(set (match_dup 2) (match_dup 4))
7527    (set (match_dup 3) (match_dup 5))]
7529   int endian = (WORDS_BIG_ENDIAN == 0);
7530   long l[2];
7532   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7534   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7535   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7536   operands[4] = gen_int_mode (l[endian], SImode);
7537   operands[5] = gen_int_mode (l[1 - endian], SImode);
7540 (define_split
7541   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7542         (match_operand:FMOVE64 1 "const_double_operand"))]
7543   "TARGET_POWERPC64 && reload_completed
7544    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7545        || (SUBREG_P (operands[0])
7546            && REG_P (SUBREG_REG (operands[0]))
7547            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7548   [(set (match_dup 2) (match_dup 3))]
7550   int endian = (WORDS_BIG_ENDIAN == 0);
7551   long l[2];
7552   HOST_WIDE_INT val;
7554   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7556   operands[2] = gen_lowpart (DImode, operands[0]);
7557   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7558   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7559          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7561   operands[3] = gen_int_mode (val, DImode);
7564 ;; Don't have reload use general registers to load a constant.  It is
7565 ;; less efficient than loading the constant into an FP register, since
7566 ;; it will probably be used there.
7568 ;; The move constraints are ordered to prefer floating point registers before
7569 ;; general purpose registers to avoid doing a store and a load to get the value
7570 ;; into a floating point register when it is needed for a floating point
7571 ;; operation.  Prefer traditional floating point registers over VSX registers,
7572 ;; since the D-form version of the memory instructions does not need a GPR for
7573 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7574 ;; registers.
7576 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7577 ;; except for 0.0 which can be created on VSX with an xor instruction.
7579 ;;           STFD         LFD         FMR         LXSD        STXSD
7580 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7581 ;;           LWZ          STW         MR
7584 (define_insn "*mov<mode>_hardfloat32"
7585   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7586             "=m,          d,          d,          <f64_p9>,   wY,
7587               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7588               Y,          r,          !r")
7589         (match_operand:FMOVE64 1 "input_operand"
7590              "d,          m,          d,          wY,         <f64_p9>,
7591               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7592               r,          Y,          r"))]
7593   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7594    && (gpc_reg_operand (operands[0], <MODE>mode)
7595        || gpc_reg_operand (operands[1], <MODE>mode))"
7596   "@
7597    stfd%U0%X0 %1,%0
7598    lfd%U1%X1 %0,%1
7599    fmr %0,%1
7600    lxsd %0,%1
7601    stxsd %1,%0
7602    lxsdx %x0,%y1
7603    stxsdx %x1,%y0
7604    xxlor %x0,%x1,%x1
7605    xxlxor %x0,%x0,%x0
7606    #
7607    #
7608    #
7609    #"
7610   [(set_attr "type"
7611             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7612              fpload,      fpstore,    veclogical, veclogical, two,
7613              store,       load,       two")
7614    (set_attr "size" "64")
7615    (set_attr "length"
7616             "*,           *,          *,          *,          *,
7617              *,           *,          *,          *,          8,
7618              8,           8,          8")
7619    (set_attr "isa"
7620             "*,           *,          *,          p9v,        p9v,
7621              p7v,         p7v,        *,          *,          *,
7622              *,           *,          *")])
7624 ;;           STW      LWZ     MR      G-const H-const F-const
7626 (define_insn "*mov<mode>_softfloat32"
7627   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7628            "=Y,       r,      r,      r,      r,      r")
7630         (match_operand:FMOVE64 1 "input_operand"
7631             "r,       Y,      r,      G,      H,      F"))]
7633   "!TARGET_POWERPC64
7634    && (gpc_reg_operand (operands[0], <MODE>mode)
7635        || gpc_reg_operand (operands[1], <MODE>mode))"
7636   "#"
7637   [(set_attr "type"
7638             "store,   load,   two,    *,      *,      *")
7640    (set_attr "length"
7641              "8,      8,      8,      8,      12,     16")])
7643 ; ld/std require word-aligned displacements -> 'Y' constraint.
7644 ; List Y->r and r->Y before r->r for reload.
7646 ;;           STFD         LFD         FMR         LXSD        STXSD
7647 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7648 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7649 ;;           NOP          MFVSRD      MTVSRD
7651 (define_insn "*mov<mode>_hardfloat64"
7652   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7653            "=m,           d,          d,          <f64_p9>,   wY,
7654              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7655              YZ,          r,          !r,         *c*l,       !r,
7656             *h,           r,          <f64_dm>")
7657         (match_operand:FMOVE64 1 "input_operand"
7658             "d,           m,          d,          wY,         <f64_p9>,
7659              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7660              r,           YZ,         r,          r,          *h,
7661              0,           <f64_dm>,   r"))]
7662   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7663    && (gpc_reg_operand (operands[0], <MODE>mode)
7664        || gpc_reg_operand (operands[1], <MODE>mode))"
7665   "@
7666    stfd%U0%X0 %1,%0
7667    lfd%U1%X1 %0,%1
7668    fmr %0,%1
7669    lxsd %0,%1
7670    stxsd %1,%0
7671    lxsdx %x0,%y1
7672    stxsdx %x1,%y0
7673    xxlor %x0,%x1,%x1
7674    xxlxor %x0,%x0,%x0
7675    li %0,0
7676    std%U0%X0 %1,%0
7677    ld%U1%X1 %0,%1
7678    mr %0,%1
7679    mt%0 %1
7680    mf%1 %0
7681    nop
7682    mfvsrd %0,%x1
7683    mtvsrd %x0,%1"
7684   [(set_attr "type"
7685             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7686              fpload,      fpstore,    veclogical, veclogical, integer,
7687              store,       load,       *,          mtjmpr,     mfjmpr,
7688              *,           mftgpr,     mffgpr")
7689    (set_attr "size" "64")
7690    (set_attr "isa"
7691             "*,           *,          *,          p9v,        p9v,
7692              p7v,         p7v,        *,          *,          *,
7693              *,           *,          *,          *,          *,
7694              *,           p8v,        p8v")])
7696 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7697 ;;           H-const  F-const  Special
7699 (define_insn "*mov<mode>_softfloat64"
7700   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7701            "=Y,       r,      r,      *c*l,   r,      r,
7702              r,       r,      *h")
7704         (match_operand:FMOVE64 1 "input_operand"
7705             "r,       Y,      r,      r,      *h,     G,
7706              H,       F,      0"))]
7708   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7709    && (gpc_reg_operand (operands[0], <MODE>mode)
7710        || gpc_reg_operand (operands[1], <MODE>mode))"
7711   "@
7712    std%U0%X0 %1,%0
7713    ld%U1%X1 %0,%1
7714    mr %0,%1
7715    mt%0 %1
7716    mf%1 %0
7717    #
7718    #
7719    #
7720    nop"
7721   [(set_attr "type"
7722             "store,   load,   *,      mtjmpr, mfjmpr, *,
7723              *,       *,      *")
7725    (set_attr "length"
7726             "*,       *,      *,      *,      *,      8,
7727              12,      16,     *")])
7729 (define_expand "mov<mode>"
7730   [(set (match_operand:FMOVE128 0 "general_operand")
7731         (match_operand:FMOVE128 1 "any_operand"))]
7732   ""
7734   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7735   DONE;
7738 ;; It's important to list Y->r and r->Y before r->r because otherwise
7739 ;; reload, given m->r, will try to pick r->r and reload it, which
7740 ;; doesn't make progress.
7742 ;; We can't split little endian direct moves of TDmode, because the words are
7743 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7744 ;; problematical.  Don't allow direct move for this case.
7746 ;;              FPR load    FPR store   FPR move    FPR zero    GPR load
7747 ;;              GPR zero    GPR store   GPR move    MFVSRD      MTVSRD
7749 (define_insn_and_split "*mov<mode>_64bit_dm"
7750   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7751                 "=m,        d,          d,          d,          Y,
7752                  r,         r,          r,          r,          d")
7754         (match_operand:FMOVE128_FPR 1 "input_operand"
7755                 "d,         m,          d,          <zero_fp>,  r,
7756                  <zero_fp>, Y,          r,          d,          r"))]
7758   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7759    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7760    && (gpc_reg_operand (operands[0], <MODE>mode)
7761        || gpc_reg_operand (operands[1], <MODE>mode))"
7762   "#"
7763   "&& reload_completed"
7764   [(pc)]
7766   rs6000_split_multireg_move (operands[0], operands[1]);
7767   DONE;
7769   [(set_attr "length" "8")
7770    (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7771    (set_attr "max_prefixed_insns" "2")
7772    (set_attr "num_insns" "2")])
7774 (define_insn_and_split "*movtd_64bit_nodm"
7775   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7776         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7777   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7778    && (gpc_reg_operand (operands[0], TDmode)
7779        || gpc_reg_operand (operands[1], TDmode))"
7780   "#"
7781   "&& reload_completed"
7782   [(pc)]
7784   rs6000_split_multireg_move (operands[0], operands[1]);
7785   DONE;
7787   [(set_attr "length" "8,8,8,12,12,8")
7788    (set_attr "max_prefixed_insns" "2")
7789    (set_attr "num_insns" "2,2,2,3,3,2")])
7791 (define_insn_and_split "*mov<mode>_32bit"
7792   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7793         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7794   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7795    && (FLOAT128_2REG_P (<MODE>mode)
7796        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7797        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7798    && (gpc_reg_operand (operands[0], <MODE>mode)
7799        || gpc_reg_operand (operands[1], <MODE>mode))"
7800   "#"
7801   "&& reload_completed"
7802   [(pc)]
7804   rs6000_split_multireg_move (operands[0], operands[1]);
7805   DONE;
7807   [(set_attr "length" "8,8,8,8,20,20,16")])
7809 (define_insn_and_split "*mov<mode>_softfloat"
7810   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7811         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7812   "TARGET_SOFT_FLOAT
7813    && (gpc_reg_operand (operands[0], <MODE>mode)
7814        || gpc_reg_operand (operands[1], <MODE>mode))"
7815   "#"
7816   "&& reload_completed"
7817   [(pc)]
7819   rs6000_split_multireg_move (operands[0], operands[1]);
7820   DONE;
7822   [(set_attr_alternative "length"
7823        [(if_then_else (match_test "TARGET_POWERPC64")
7824             (const_string "8")
7825             (const_string "16"))
7826         (if_then_else (match_test "TARGET_POWERPC64")
7827             (const_string "8")
7828             (const_string "16"))
7829         (if_then_else (match_test "TARGET_POWERPC64")
7830             (const_string "16")
7831             (const_string "32"))
7832         (if_then_else (match_test "TARGET_POWERPC64")
7833             (const_string "8")
7834             (const_string "16"))])])
7836 (define_expand "@extenddf<mode>2"
7837   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7838         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7839   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7841   if (FLOAT128_IEEE_P (<MODE>mode))
7842     rs6000_expand_float128_convert (operands[0], operands[1], false);
7843   else if (TARGET_VSX)
7844     emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7845   else
7846     {
7847       rtx zero = gen_reg_rtx (DFmode);
7848       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7850       emit_insn (gen_extenddf2_fprs (<MODE>mode,
7851                                      operands[0], operands[1], zero));
7852     }
7853   DONE;
7856 ;; Allow memory operands for the source to be created by the combiner.
7857 (define_insn_and_split "@extenddf<mode>2_fprs"
7858   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7859         (float_extend:IBM128
7860          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7861    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7862   "!TARGET_VSX && TARGET_HARD_FLOAT
7863    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7864   "#"
7865   "&& reload_completed"
7866   [(set (match_dup 3) (match_dup 1))
7867    (set (match_dup 4) (match_dup 2))]
7869   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7870   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7872   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7873   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7876 (define_insn_and_split "@extenddf<mode>2_vsx"
7877   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7878         (float_extend:IBM128
7879          (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7880   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7881   "#"
7882   "&& reload_completed"
7883   [(set (match_dup 2) (match_dup 1))
7884    (set (match_dup 3) (match_dup 4))]
7886   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7887   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7889   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7890   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7891   operands[4] = CONST0_RTX (DFmode);
7894 (define_expand "extendsf<mode>2"
7895   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7896         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7897   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7899   if (FLOAT128_IEEE_P (<MODE>mode))
7900     rs6000_expand_float128_convert (operands[0], operands[1], false);
7901   else
7902     {
7903       rtx tmp = gen_reg_rtx (DFmode);
7904       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7905       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7906     }
7907   DONE;
7910 (define_expand "trunc<mode>df2"
7911   [(set (match_operand:DF 0 "gpc_reg_operand")
7912         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7913   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7915   if (FLOAT128_IEEE_P (<MODE>mode))
7916     {
7917       rs6000_expand_float128_convert (operands[0], operands[1], false);
7918       DONE;
7919     }
7922 (define_insn_and_split "trunc<mode>df2_internal1"
7923   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7924         (float_truncate:DF
7925          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7926   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7927    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7928   "@
7929    #
7930    fmr %0,%1"
7931   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7932   [(const_int 0)]
7934   emit_note (NOTE_INSN_DELETED);
7935   DONE;
7937   [(set_attr "type" "fpsimple")])
7939 (define_insn "trunc<mode>df2_internal2"
7940   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7941         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7942   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7943    && TARGET_LONG_DOUBLE_128"
7944   "fadd %0,%1,%L1"
7945   [(set_attr "type" "fp")])
7947 (define_expand "trunc<mode>sf2"
7948   [(set (match_operand:SF 0 "gpc_reg_operand")
7949         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7950   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7952   if (FLOAT128_IEEE_P (<MODE>mode))
7953     rs6000_expand_float128_convert (operands[0], operands[1], false);
7954   else
7955     {
7956       rtx tmp = gen_reg_rtx (DFmode);
7957       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7958       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7959     }
7960   DONE;
7963 (define_expand "floatsi<mode>2"
7964   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7965                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7966               (clobber (match_scratch:DI 2))])]
7967   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7969   rtx op0 = operands[0];
7970   rtx op1 = operands[1];
7972   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7973     ;
7974   else if (FLOAT128_IEEE_P (<MODE>mode))
7975     {
7976       rs6000_expand_float128_convert (op0, op1, false);
7977       DONE;
7978     }
7979   else
7980     {
7981       rtx tmp = gen_reg_rtx (DFmode);
7982       expand_float (tmp, op1, false);
7983       emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
7984       DONE;
7985     }
7988 ; fadd, but rounding towards zero.
7989 ; This is probably not the optimal code sequence.
7990 (define_insn "fix_trunc_helper<mode>"
7991   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7992         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7993                    UNSPEC_FIX_TRUNC_TF))
7994    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7995   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7996   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7997   [(set_attr "type" "fp")
7998    (set_attr "length" "20")])
8000 (define_expand "fix_trunc<mode>si2"
8001   [(set (match_operand:SI 0 "gpc_reg_operand")
8002         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8003   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8005   rtx op0 = operands[0];
8006   rtx op1 = operands[1];
8008   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8009     ;
8010   else
8011     {
8012       if (FLOAT128_IEEE_P (<MODE>mode))
8013         rs6000_expand_float128_convert (op0, op1, false);
8014       else
8015         emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8016       DONE;
8017     }
8020 (define_expand "@fix_trunc<mode>si2_fprs"
8021   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8022                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8023               (clobber (match_dup 2))
8024               (clobber (match_dup 3))
8025               (clobber (match_dup 4))
8026               (clobber (match_dup 5))])]
8027   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8029   operands[2] = gen_reg_rtx (DFmode);
8030   operands[3] = gen_reg_rtx (DFmode);
8031   operands[4] = gen_reg_rtx (DImode);
8032   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8035 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8036   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8037         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8038    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8039    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8040    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8041    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8042   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8043   "#"
8044   ""
8045   [(pc)]
8047   rtx lowword;
8048   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8049                                          operands[3]));
8051   gcc_assert (MEM_P (operands[5]));
8052   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8054   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8055   emit_move_insn (operands[5], operands[4]);
8056   emit_move_insn (operands[0], lowword);
8057   DONE;
8060 (define_expand "fix_trunc<mode>di2"
8061   [(set (match_operand:DI 0 "gpc_reg_operand")
8062         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8063   "TARGET_FLOAT128_TYPE"
8065   if (!TARGET_FLOAT128_HW)
8066     {
8067       rs6000_expand_float128_convert (operands[0], operands[1], false);
8068       DONE;
8069     }
8072 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8073   [(set (match_operand:SDI 0 "gpc_reg_operand")
8074         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8075   "TARGET_FLOAT128_TYPE"
8077   rs6000_expand_float128_convert (operands[0], operands[1], true);
8078   DONE;
8081 (define_expand "floatdi<mode>2"
8082   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8083         (float:IEEE128 (match_operand:DI 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 "floatunsdi<IEEE128:mode>2"
8094   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8095         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8096   "TARGET_FLOAT128_TYPE"
8098   if (!TARGET_FLOAT128_HW)
8099     {
8100       rs6000_expand_float128_convert (operands[0], operands[1], true);
8101       DONE;
8102     }
8105 (define_expand "floatuns<IEEE128:mode>2"
8106   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8107         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8108   "TARGET_FLOAT128_TYPE"
8110   rtx op0 = operands[0];
8111   rtx op1 = operands[1];
8113   if (TARGET_FLOAT128_HW)
8114     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8115   else
8116     rs6000_expand_float128_convert (op0, op1, true);
8117   DONE;
8120 (define_expand "neg<mode>2"
8121   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8122         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8123   "FLOAT128_IEEE_P (<MODE>mode)
8124    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8126   if (FLOAT128_IEEE_P (<MODE>mode))
8127     {
8128       if (TARGET_FLOAT128_HW)
8129         emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8130       else if (TARGET_FLOAT128_TYPE)
8131         emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8132                                              operands[0], operands[1]));
8133       else
8134         {
8135           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8136           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8137                                                 <MODE>mode,
8138                                                 operands[1], <MODE>mode);
8140           if (target && !rtx_equal_p (target, operands[0]))
8141             emit_move_insn (operands[0], target);
8142         }
8143       DONE;
8144     }
8147 (define_insn "neg<mode>2_internal"
8148   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8149         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8150   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8152   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8153     return "fneg %L0,%L1\;fneg %0,%1";
8154   else
8155     return "fneg %0,%1\;fneg %L0,%L1";
8157   [(set_attr "type" "fpsimple")
8158    (set_attr "length" "8")])
8160 (define_expand "abs<mode>2"
8161   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8162         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8163   "FLOAT128_IEEE_P (<MODE>mode)
8164    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8166   rtx label;
8168   if (FLOAT128_IEEE_P (<MODE>mode))
8169     {
8170       if (TARGET_FLOAT128_HW)
8171         {
8172           emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8173           DONE;
8174         }
8175       else if (TARGET_FLOAT128_TYPE)
8176         {
8177           emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8178                                                operands[0], operands[1]));
8179           DONE;
8180         }
8181       else
8182         FAIL;
8183     }
8185   label = gen_label_rtx ();
8186   emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8187   emit_label (label);
8188   DONE;
8191 (define_expand "@abs<mode>2_internal"
8192   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8193         (match_operand:IBM128 1 "gpc_reg_operand"))
8194    (set (match_dup 3) (match_dup 5))
8195    (set (match_dup 5) (abs:DF (match_dup 5)))
8196    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8197    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8198                            (label_ref (match_operand 2 ""))
8199                            (pc)))
8200    (set (match_dup 6) (neg:DF (match_dup 6)))]
8201   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8203   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8204   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8205   operands[3] = gen_reg_rtx (DFmode);
8206   operands[4] = gen_reg_rtx (CCFPmode);
8207   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8208   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8212 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8213 ;; register
8215 (define_expand "ieee_128bit_negative_zero"
8216   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8217   "TARGET_FLOAT128_TYPE"
8219   rtvec v = rtvec_alloc (16);
8220   int i, high;
8222   for (i = 0; i < 16; i++)
8223     RTVEC_ELT (v, i) = const0_rtx;
8225   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8226   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8228   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8229   DONE;
8232 ;; IEEE 128-bit negate
8234 ;; We have 2 insns here for negate and absolute value.  The first uses
8235 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8236 ;; insns, and second insn after the first split pass loads up the bit to
8237 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8238 ;; neg/abs to create the constant just once.
8240 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8241   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8242         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8243    (clobber (match_scratch:V16QI 2 "=v"))]
8244   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8245   "#"
8246   "&& 1"
8247   [(parallel [(set (match_dup 0)
8248                    (neg:IEEE128 (match_dup 1)))
8249               (use (match_dup 2))])]
8251   if (GET_CODE (operands[2]) == SCRATCH)
8252     operands[2] = gen_reg_rtx (V16QImode);
8254   operands[3] = gen_reg_rtx (V16QImode);
8255   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8257   [(set_attr "length" "8")
8258    (set_attr "type" "vecsimple")])
8260 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8261   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8262         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8263    (use (match_operand:V16QI 2 "register_operand" "v"))]
8264   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8265   "xxlxor %x0,%x1,%x2"
8266   [(set_attr "type" "veclogical")])
8268 ;; IEEE 128-bit absolute value
8269 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8270   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8271         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8272    (clobber (match_scratch:V16QI 2 "=v"))]
8273   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8274   "#"
8275   "&& 1"
8276   [(parallel [(set (match_dup 0)
8277                    (abs:IEEE128 (match_dup 1)))
8278               (use (match_dup 2))])]
8280   if (GET_CODE (operands[2]) == SCRATCH)
8281     operands[2] = gen_reg_rtx (V16QImode);
8283   operands[3] = gen_reg_rtx (V16QImode);
8284   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8286   [(set_attr "length" "8")
8287    (set_attr "type" "vecsimple")])
8289 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8290   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8291         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8292    (use (match_operand:V16QI 2 "register_operand" "v"))]
8293   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8294   "xxlandc %x0,%x1,%x2"
8295   [(set_attr "type" "veclogical")])
8297 ;; IEEE 128-bit negative absolute value
8298 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8299   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8300         (neg:IEEE128
8301          (abs:IEEE128
8302           (match_operand:IEEE128 1 "register_operand" "wa"))))
8303    (clobber (match_scratch:V16QI 2 "=v"))]
8304   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8305    && FLOAT128_IEEE_P (<MODE>mode)"
8306   "#"
8307   "&& 1"
8308   [(parallel [(set (match_dup 0)
8309                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8310               (use (match_dup 2))])]
8312   if (GET_CODE (operands[2]) == SCRATCH)
8313     operands[2] = gen_reg_rtx (V16QImode);
8315   operands[3] = gen_reg_rtx (V16QImode);
8316   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8318   [(set_attr "length" "8")
8319    (set_attr "type" "vecsimple")])
8321 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8322   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8323         (neg:IEEE128
8324          (abs:IEEE128
8325           (match_operand:IEEE128 1 "register_operand" "wa"))))
8326    (use (match_operand:V16QI 2 "register_operand" "v"))]
8327   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8328   "xxlor %x0,%x1,%x2"
8329   [(set_attr "type" "veclogical")])
8331 ;; Float128 conversion functions.  These expand to library function calls.
8332 ;; We use expand to convert from IBM double double to IEEE 128-bit
8333 ;; and trunc for the opposite.
8334 (define_expand "extendiftf2"
8335   [(set (match_operand:TF 0 "gpc_reg_operand")
8336         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8337   "TARGET_FLOAT128_TYPE"
8339   rs6000_expand_float128_convert (operands[0], operands[1], false);
8340   DONE;
8343 (define_expand "extendifkf2"
8344   [(set (match_operand:KF 0 "gpc_reg_operand")
8345         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8346   "TARGET_FLOAT128_TYPE"
8348   rs6000_expand_float128_convert (operands[0], operands[1], false);
8349   DONE;
8352 (define_expand "extendtfkf2"
8353   [(set (match_operand:KF 0 "gpc_reg_operand")
8354         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8355   "TARGET_FLOAT128_TYPE"
8357   rs6000_expand_float128_convert (operands[0], operands[1], false);
8358   DONE;
8361 (define_expand "extendtfif2"
8362   [(set (match_operand:IF 0 "gpc_reg_operand")
8363         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8364   "TARGET_FLOAT128_TYPE"
8366   rs6000_expand_float128_convert (operands[0], operands[1], false);
8367   DONE;
8370 (define_expand "trunciftf2"
8371   [(set (match_operand:TF 0 "gpc_reg_operand")
8372         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8373   "TARGET_FLOAT128_TYPE"
8375   rs6000_expand_float128_convert (operands[0], operands[1], false);
8376   DONE;
8379 (define_expand "truncifkf2"
8380   [(set (match_operand:KF 0 "gpc_reg_operand")
8381         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8382   "TARGET_FLOAT128_TYPE"
8384   rs6000_expand_float128_convert (operands[0], operands[1], false);
8385   DONE;
8388 (define_expand "trunckftf2"
8389   [(set (match_operand:TF 0 "gpc_reg_operand")
8390         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8391   "TARGET_FLOAT128_TYPE"
8393   rs6000_expand_float128_convert (operands[0], operands[1], false);
8394   DONE;
8397 (define_expand "trunctfif2"
8398   [(set (match_operand:IF 0 "gpc_reg_operand")
8399         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8400   "TARGET_FLOAT128_TYPE"
8402   rs6000_expand_float128_convert (operands[0], operands[1], false);
8403   DONE;
8406 (define_insn_and_split "*extend<mode>tf2_internal"
8407   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8408         (float_extend:TF
8409          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8410    "TARGET_FLOAT128_TYPE
8411     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8412   "#"
8413   "&& reload_completed"
8414   [(set (match_dup 0) (match_dup 2))]
8416   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8419 (define_insn_and_split "*extendtf<mode>2_internal"
8420   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8421         (float_extend:IFKF
8422          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8423    "TARGET_FLOAT128_TYPE
8424     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8425   "#"
8426   "&& reload_completed"
8427   [(set (match_dup 0) (match_dup 2))]
8429   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8433 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8434 ;; must have 3 arguments, and scratch register constraint must be a single
8435 ;; constraint.
8437 ;; Reload patterns to support gpr load/store with misaligned mem.
8438 ;; and multiple gpr load/store at offset >= 0xfffc
8439 (define_expand "reload_<mode>_store"
8440   [(parallel [(match_operand 0 "memory_operand" "=m")
8441               (match_operand 1 "gpc_reg_operand" "r")
8442               (match_operand:GPR 2 "register_operand" "=&b")])]
8443   ""
8445   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8446   DONE;
8449 (define_expand "reload_<mode>_load"
8450   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8451               (match_operand 1 "memory_operand" "m")
8452               (match_operand:GPR 2 "register_operand" "=b")])]
8453   ""
8455   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8456   DONE;
8460 ;; Reload patterns for various types using the vector registers.  We may need
8461 ;; an additional base register to convert the reg+offset addressing to reg+reg
8462 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8463 ;; index register for gpr registers.
8464 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8465   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8466               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8467               (match_operand:P 2 "register_operand" "=b")])]
8468   "<P:tptrsize>"
8470   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8471   DONE;
8474 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8475   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8476               (match_operand:RELOAD 1 "memory_operand" "m")
8477               (match_operand:P 2 "register_operand" "=b")])]
8478   "<P:tptrsize>"
8480   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8481   DONE;
8485 ;; Reload sometimes tries to move the address to a GPR, and can generate
8486 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8487 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8489 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8490   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8491         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8492                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8493                (const_int -16)))]
8494   "TARGET_ALTIVEC && reload_completed"
8495   "#"
8496   "&& reload_completed"
8497   [(set (match_dup 0)
8498         (plus:P (match_dup 1)
8499                 (match_dup 2)))
8500    (set (match_dup 0)
8501         (and:P (match_dup 0)
8502                (const_int -16)))])
8504 ;; Power8 merge instructions to allow direct move to/from floating point
8505 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8506 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8507 ;; value, since it is allocated in reload and not all of the flow information
8508 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8509 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8510 ;; schedule other instructions between the two instructions.
8512 (define_insn "p8_fmrgow_<mode>"
8513   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8514         (unspec:FMOVE64X [
8515                 (match_operand:DF 1 "register_operand" "d")
8516                 (match_operand:DF 2 "register_operand" "d")]
8517                          UNSPEC_P8V_FMRGOW))]
8518   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8519   "fmrgow %0,%1,%2"
8520   [(set_attr "type" "fpsimple")])
8522 (define_insn "p8_mtvsrwz"
8523   [(set (match_operand:DF 0 "register_operand" "=d")
8524         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8525                    UNSPEC_P8V_MTVSRWZ))]
8526   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8527   "mtvsrwz %x0,%1"
8528   [(set_attr "type" "mftgpr")])
8530 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8531   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8532         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8533                          UNSPEC_P8V_RELOAD_FROM_GPR))
8534    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8535   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8536   "#"
8537   "&& reload_completed"
8538   [(const_int 0)]
8540   rtx dest = operands[0];
8541   rtx src = operands[1];
8542   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8543   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8544   rtx gpr_hi_reg = gen_highpart (SImode, src);
8545   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8547   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8548   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8549   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8550   DONE;
8552   [(set_attr "length" "12")
8553    (set_attr "type" "three")])
8555 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8556 (define_insn "p8_mtvsrd_df"
8557   [(set (match_operand:DF 0 "register_operand" "=wa")
8558         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8559                    UNSPEC_P8V_MTVSRD))]
8560   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8561   "mtvsrd %x0,%1"
8562   [(set_attr "type" "mftgpr")])
8564 (define_insn "p8_xxpermdi_<mode>"
8565   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8566         (unspec:FMOVE128_GPR [
8567                 (match_operand:DF 1 "register_operand" "wa")
8568                 (match_operand:DF 2 "register_operand" "wa")]
8569                 UNSPEC_P8V_XXPERMDI))]
8570   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8571   "xxpermdi %x0,%x1,%x2,0"
8572   [(set_attr "type" "vecperm")])
8574 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8575   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8576         (unspec:FMOVE128_GPR
8577          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8578          UNSPEC_P8V_RELOAD_FROM_GPR))
8579    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8580   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8581   "#"
8582   "&& reload_completed"
8583   [(const_int 0)]
8585   rtx dest = operands[0];
8586   rtx src = operands[1];
8587   /* You might think that we could use op0 as one temp and a DF clobber
8588      as op2, but you'd be wrong.  Secondary reload move patterns don't
8589      check for overlap of the clobber and the destination.  */
8590   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8591   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8592   rtx gpr_hi_reg = gen_highpart (DImode, src);
8593   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8595   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8596   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8597   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8598   DONE;
8600   [(set_attr "length" "12")
8601    (set_attr "type" "three")])
8603 (define_split
8604   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8605         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8606   "reload_completed
8607    && (int_reg_operand (operands[0], <MODE>mode)
8608        || int_reg_operand (operands[1], <MODE>mode))
8609    && (!TARGET_DIRECT_MOVE_128
8610        || (!vsx_register_operand (operands[0], <MODE>mode)
8611            && !vsx_register_operand (operands[1], <MODE>mode)))"
8612   [(pc)]
8614   rs6000_split_multireg_move (operands[0], operands[1]);
8615   DONE;
8618 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8619 ;; type is stored internally as double precision in the VSX registers, we have
8620 ;; to convert it from the vector format.
8621 (define_insn "p8_mtvsrd_sf"
8622   [(set (match_operand:SF 0 "register_operand" "=wa")
8623         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8624                    UNSPEC_P8V_MTVSRD))]
8625   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8626   "mtvsrd %x0,%1"
8627   [(set_attr "type" "mftgpr")])
8629 (define_insn_and_split "reload_vsx_from_gprsf"
8630   [(set (match_operand:SF 0 "register_operand" "=wa")
8631         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8632                    UNSPEC_P8V_RELOAD_FROM_GPR))
8633    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8634   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8635   "#"
8636   "&& reload_completed"
8637   [(const_int 0)]
8639   rtx op0 = operands[0];
8640   rtx op1 = operands[1];
8641   rtx op2 = operands[2];
8642   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8644   /* Move SF value to upper 32-bits for xscvspdpn.  */
8645   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8646   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8647   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8648   DONE;
8650   [(set_attr "length" "8")
8651    (set_attr "type" "two")])
8653 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8654 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8655 ;; and then doing a move of that.
8656 (define_insn "p8_mfvsrd_3_<mode>"
8657   [(set (match_operand:DF 0 "register_operand" "=r")
8658         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8659                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8660   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8661   "mfvsrd %0,%x1"
8662   [(set_attr "type" "mftgpr")])
8664 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8665   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8666         (unspec:FMOVE128_GPR
8667          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8668          UNSPEC_P8V_RELOAD_FROM_VSX))
8669    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8670   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8671   "#"
8672   "&& reload_completed"
8673   [(const_int 0)]
8675   rtx dest = operands[0];
8676   rtx src = operands[1];
8677   rtx tmp = operands[2];
8678   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8679   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8681   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8682   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8683   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8684   DONE;
8686   [(set_attr "length" "12")
8687    (set_attr "type" "three")])
8689 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8690 ;; type is stored internally as double precision, we have to convert it to the
8691 ;; vector format.
8693 (define_insn_and_split "reload_gpr_from_vsxsf"
8694   [(set (match_operand:SF 0 "register_operand" "=r")
8695         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8696                    UNSPEC_P8V_RELOAD_FROM_VSX))
8697    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8698   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8699   "#"
8700   "&& reload_completed"
8701   [(const_int 0)]
8703   rtx op0 = operands[0];
8704   rtx op1 = operands[1];
8705   rtx op2 = operands[2];
8706   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8707   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8709   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8710   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8711   DONE;
8713   [(set_attr "length" "8")
8714    (set_attr "type" "two")
8715    (set_attr "isa" "p8v")])
8717 ;; Next come the multi-word integer load and store and the load and store
8718 ;; multiple insns.
8720 ;; List r->r after r->Y, otherwise reload will try to reload a
8721 ;; non-offsettable address by using r->r which won't make progress.
8722 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8723 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8725 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8726 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8727 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8728 ;;        AVX const  
8730 (define_insn "*movdi_internal32"
8731   [(set (match_operand:DI 0 "nonimmediate_operand"
8732          "=Y,        r,         r,         m,         ^d,        ^d,
8733           r,         wY,        Z,         ^v,        $v,        ^wa,
8734           wa,        wa,        v,         wa,        *i,        v,
8735           v")
8736         (match_operand:DI 1 "input_operand"
8737          "r,         Y,         r,         ^d,        m,         ^d,
8738           IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8739           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8740           wB"))]
8741   "! TARGET_POWERPC64
8742    && (gpc_reg_operand (operands[0], DImode)
8743        || gpc_reg_operand (operands[1], DImode))"
8744   "@
8745    #
8746    #
8747    #
8748    stfd%U0%X0 %1,%0
8749    lfd%U1%X1 %0,%1
8750    fmr %0,%1
8751    #
8752    stxsd %1,%0
8753    stxsdx %x1,%y0
8754    lxsd %0,%1
8755    lxsdx %x0,%y1
8756    xxlor %x0,%x1,%x1
8757    xxspltib %x0,0
8758    xxspltib %x0,255
8759    vspltisw %0,%1
8760    xxlxor %x0,%x0,%x0
8761    xxlorc %x0,%x0,%x0
8762    #
8763    #"
8764   [(set_attr "type"
8765          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8766           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8767           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8768           vecsimple")
8769    (set_attr "size" "64")
8770    (set_attr "length"
8771          "8,         8,         8,         *,         *,         *,
8772           16,        *,         *,         *,         *,         *,
8773           *,         *,         *,         *,         *,         8,
8774           *")
8775    (set_attr "isa"
8776          "*,         *,         *,         *,         *,         *,
8777           *,         p9v,       p7v,       p9v,       p7v,       *,
8778           p9v,       p9v,       p7v,       *,         *,         p7v,
8779           p7v")])
8781 (define_split
8782   [(set (match_operand:DI 0 "gpc_reg_operand")
8783         (match_operand:DI 1 "const_int_operand"))]
8784   "! TARGET_POWERPC64 && reload_completed
8785    && gpr_or_gpr_p (operands[0], operands[1])
8786    && !direct_move_p (operands[0], operands[1])"
8787   [(set (match_dup 2) (match_dup 4))
8788    (set (match_dup 3) (match_dup 1))]
8790   HOST_WIDE_INT value = INTVAL (operands[1]);
8791   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8792                                        DImode);
8793   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8794                                        DImode);
8795   operands[4] = GEN_INT (value >> 32);
8796   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8799 (define_split
8800   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8801         (match_operand:DIFD 1 "input_operand"))]
8802   "reload_completed && !TARGET_POWERPC64
8803    && gpr_or_gpr_p (operands[0], operands[1])
8804    && !direct_move_p (operands[0], operands[1])"
8805   [(pc)]
8807   rs6000_split_multireg_move (operands[0], operands[1]);
8808   DONE;
8811 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8812 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8813 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8814 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8815 ;;              VSX->GPR   GPR->VSX
8816 (define_insn "*movdi_internal64"
8817   [(set (match_operand:DI 0 "nonimmediate_operand"
8818                "=YZ,       r,         r,         r,         r,          r,
8819                 m,         ^d,        ^d,        wY,        Z,          $v,
8820                 $v,        ^wa,       wa,        wa,        v,          wa,
8821                 wa,        v,         v,         r,         *h,         *h,
8822                 ?r,        ?wa")
8823         (match_operand:DI 1 "input_operand"
8824                "r,         YZ,        r,         I,         L,          nF,
8825                 ^d,        m,         ^d,        ^v,        $v,         wY,
8826                 Z,         ^wa,       Oj,        wM,        OjwM,       Oj,
8827                 wM,        wS,        wB,        *h,        r,          0,
8828                 wa,        r"))]
8829   "TARGET_POWERPC64
8830    && (gpc_reg_operand (operands[0], DImode)
8831        || gpc_reg_operand (operands[1], DImode))"
8832   "@
8833    std%U0%X0 %1,%0
8834    ld%U1%X1 %0,%1
8835    mr %0,%1
8836    li %0,%1
8837    lis %0,%v1
8838    #
8839    stfd%U0%X0 %1,%0
8840    lfd%U1%X1 %0,%1
8841    fmr %0,%1
8842    stxsd %1,%0
8843    stxsdx %x1,%y0
8844    lxsd %0,%1
8845    lxsdx %x0,%y1
8846    xxlor %x0,%x1,%x1
8847    xxspltib %x0,0
8848    xxspltib %x0,255
8849    #
8850    xxlxor %x0,%x0,%x0
8851    xxlorc %x0,%x0,%x0
8852    #
8853    #
8854    mf%1 %0
8855    mt%0 %1
8856    nop
8857    mfvsrd %0,%x1
8858    mtvsrd %x0,%1"
8859   [(set_attr "type"
8860                "store,      load,       *,         *,         *,         *,
8861                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8862                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8863                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8864                 mftgpr,    mffgpr")
8865    (set_attr "size" "64")
8866    (set_attr "length"
8867                "*,         *,         *,         *,         *,          20,
8868                 *,         *,         *,         *,         *,          *,
8869                 *,         *,         *,         *,         *,          *,
8870                 *,         8,         *,         *,         *,          *,
8871                 *,         *")
8872    (set_attr "isa"
8873                "*,         *,         *,         *,         *,          *,
8874                 *,         *,         *,         p9v,       p7v,        p9v,
8875                 p7v,       *,         p9v,       p9v,       p7v,        *,
8876                 *,         p7v,       p7v,       *,         *,          *,
8877                 p8v,       p8v")])
8879 ; Some DImode loads are best done as a load of -1 followed by a mask
8880 ; instruction.
8881 (define_split
8882   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8883         (match_operand:DI 1 "const_int_operand"))]
8884   "TARGET_POWERPC64
8885    && num_insns_constant (operands[1], DImode) > 1
8886    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8887    && rs6000_is_valid_and_mask (operands[1], DImode)"
8888   [(set (match_dup 0)
8889         (const_int -1))
8890    (set (match_dup 0)
8891         (and:DI (match_dup 0)
8892                 (match_dup 1)))]
8893   "")
8895 ;; Split a load of a large constant into the appropriate five-instruction
8896 ;; sequence.  Handle anything in a constant number of insns.
8897 ;; When non-easy constants can go in the TOC, this should use
8898 ;; easy_fp_constant predicate.
8899 (define_split
8900   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8901         (match_operand:DI 1 "const_int_operand"))]
8902   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8903   [(set (match_dup 0) (match_dup 2))
8904    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8906   if (rs6000_emit_set_const (operands[0], operands[1]))
8907     DONE;
8908   else
8909     FAIL;
8912 (define_split
8913   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8914         (match_operand:DI 1 "const_scalar_int_operand"))]
8915   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8916   [(set (match_dup 0) (match_dup 2))
8917    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8919   if (rs6000_emit_set_const (operands[0], operands[1]))
8920     DONE;
8921   else
8922     FAIL;
8925 (define_split
8926   [(set (match_operand:DI 0 "altivec_register_operand")
8927         (match_operand:DI 1 "s5bit_cint_operand"))]
8928   "TARGET_VSX && reload_completed"
8929   [(const_int 0)]
8931   rtx op0 = operands[0];
8932   rtx op1 = operands[1];
8933   int r = REGNO (op0);
8934   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8936   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8937   if (op1 != const0_rtx && op1 != constm1_rtx)
8938     {
8939       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8940       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8941     }
8942   DONE;
8945 ;; Split integer constants that can be loaded with XXSPLTIB and a
8946 ;; sign extend operation.
8947 (define_split
8948   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8949         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8950   "TARGET_P9_VECTOR && reload_completed"
8951   [(const_int 0)]
8953   rtx op0 = operands[0];
8954   rtx op1 = operands[1];
8955   int r = REGNO (op0);
8956   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8958   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8959   if (<MODE>mode == DImode)
8960     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8961   else if (<MODE>mode == SImode)
8962     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8963   else if (<MODE>mode == HImode)
8964     {
8965       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8966       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8967     }
8968   DONE;
8972 ;; TImode/PTImode is similar, except that we usually want to compute the
8973 ;; address into a register and use lsi/stsi (the exception is during reload).
8975 (define_insn "*mov<mode>_string"
8976   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8977         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8978   "! TARGET_POWERPC64
8979    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8980    && (gpc_reg_operand (operands[0], <MODE>mode)
8981        || gpc_reg_operand (operands[1], <MODE>mode))"
8982   "#"
8983   [(set_attr "type" "store,store,load,load,*,*")
8984    (set_attr "update" "yes")
8985    (set_attr "indexed" "yes")
8986    (set_attr "cell_micro" "conditional")])
8988 (define_insn "*mov<mode>_ppc64"
8989   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8990         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8991   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8992    && (gpc_reg_operand (operands[0], <MODE>mode)
8993        || gpc_reg_operand (operands[1], <MODE>mode)))"
8995   return rs6000_output_move_128bit (operands);
8997   [(set_attr "type" "store,store,load,load,*,*")
8998    (set_attr "length" "8")
8999    (set_attr "max_prefixed_insns" "2")])
9001 (define_split
9002   [(set (match_operand:TI2 0 "int_reg_operand")
9003         (match_operand:TI2 1 "const_scalar_int_operand"))]
9004   "TARGET_POWERPC64
9005    && (VECTOR_MEM_NONE_P (<MODE>mode)
9006        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9007   [(set (match_dup 2) (match_dup 4))
9008    (set (match_dup 3) (match_dup 5))]
9010   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9011                                        <MODE>mode);
9012   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9013                                        <MODE>mode);
9014   if (CONST_WIDE_INT_P (operands[1]))
9015     {
9016       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9017       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9018     }
9019   else if (CONST_INT_P (operands[1]))
9020     {
9021       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9022       operands[5] = operands[1];
9023     }
9024   else
9025     FAIL;
9028 (define_split
9029   [(set (match_operand:TI2 0 "nonimmediate_operand")
9030         (match_operand:TI2 1 "input_operand"))]
9031   "reload_completed
9032    && gpr_or_gpr_p (operands[0], operands[1])
9033    && !direct_move_p (operands[0], operands[1])
9034    && !quad_load_store_p (operands[0], operands[1])"
9035   [(pc)]
9037   rs6000_split_multireg_move (operands[0], operands[1]);
9038   DONE;
9041 (define_expand "setmemsi"
9042   [(parallel [(set (match_operand:BLK 0 "")
9043                    (match_operand 2 "const_int_operand"))
9044               (use (match_operand:SI 1 ""))
9045               (use (match_operand:SI 3 ""))])]
9046   ""
9048   /* If value to set is not zero, use the library routine.  */
9049   if (operands[2] != const0_rtx)
9050     FAIL;
9052   if (expand_block_clear (operands))
9053     DONE;
9054   else
9055     FAIL;
9058 ;; String compare N insn.
9059 ;; Argument 0 is the target (result)
9060 ;; Argument 1 is the destination
9061 ;; Argument 2 is the source
9062 ;; Argument 3 is the length
9063 ;; Argument 4 is the alignment
9065 (define_expand "cmpstrnsi"
9066   [(parallel [(set (match_operand:SI 0)
9067                (compare:SI (match_operand:BLK 1)
9068                            (match_operand:BLK 2)))
9069               (use (match_operand:SI 3))
9070               (use (match_operand:SI 4))])]
9071   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9073   if (optimize_insn_for_size_p ())
9074     FAIL;
9076   if (expand_strn_compare (operands, 0))
9077     DONE;
9078   else  
9079     FAIL;
9082 ;; String compare insn.
9083 ;; Argument 0 is the target (result)
9084 ;; Argument 1 is the destination
9085 ;; Argument 2 is the source
9086 ;; Argument 3 is the alignment
9088 (define_expand "cmpstrsi"
9089   [(parallel [(set (match_operand:SI 0)
9090                (compare:SI (match_operand:BLK 1)
9091                            (match_operand:BLK 2)))
9092               (use (match_operand:SI 3))])]
9093   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9095   if (optimize_insn_for_size_p ())
9096     FAIL;
9098   if (expand_strn_compare (operands, 1))
9099     DONE;
9100   else  
9101     FAIL;
9104 ;; Block compare insn.
9105 ;; Argument 0 is the target (result)
9106 ;; Argument 1 is the destination
9107 ;; Argument 2 is the source
9108 ;; Argument 3 is the length
9109 ;; Argument 4 is the alignment
9111 (define_expand "cmpmemsi"
9112   [(parallel [(set (match_operand:SI 0)
9113                (compare:SI (match_operand:BLK 1)
9114                            (match_operand:BLK 2)))
9115               (use (match_operand:SI 3))
9116               (use (match_operand:SI 4))])]
9117   "TARGET_POPCNTD"
9119   if (expand_block_compare (operands))
9120     DONE;
9121   else
9122     FAIL;
9125 ;; String/block copy insn (source and destination must not overlap).
9126 ;; Argument 0 is the destination
9127 ;; Argument 1 is the source
9128 ;; Argument 2 is the length
9129 ;; Argument 3 is the alignment
9131 (define_expand "cpymemsi"
9132   [(parallel [(set (match_operand:BLK 0 "")
9133                    (match_operand:BLK 1 ""))
9134               (use (match_operand:SI 2 ""))
9135               (use (match_operand:SI 3 ""))])]
9136   ""
9138   if (expand_block_move (operands, false))
9139     DONE;
9140   else
9141     FAIL;
9144 ;; String/block move insn (source and destination may overlap).
9145 ;; Argument 0 is the destination
9146 ;; Argument 1 is the source
9147 ;; Argument 2 is the length
9148 ;; Argument 3 is the alignment
9150 (define_expand "movmemsi"
9151   [(parallel [(set (match_operand:BLK 0 "")
9152                    (match_operand:BLK 1 ""))
9153               (use (match_operand:SI 2 ""))
9154               (use (match_operand:SI 3 ""))])]
9155   ""
9157   if (expand_block_move (operands, true))
9158     DONE;
9159   else
9160     FAIL;
9164 ;; Define insns that do load or store with update.  Some of these we can
9165 ;; get by using pre-decrement or pre-increment, but the hardware can also
9166 ;; do cases where the increment is not the size of the object.
9168 ;; In all these cases, we use operands 0 and 1 for the register being
9169 ;; incremented because those are the operands that local-alloc will
9170 ;; tie and these are the pair most likely to be tieable (and the ones
9171 ;; that will benefit the most).
9173 (define_insn "*movdi_update1"
9174   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9175         (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9176                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9177    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9178         (plus:P (match_dup 1) (match_dup 2)))]
9179   "TARGET_POWERPC64 && TARGET_UPDATE
9180    && (!avoiding_indexed_address_p (DImode)
9181        || !gpc_reg_operand (operands[2], Pmode))"
9182   "@
9183    ldux %3,%0,%2
9184    ldu %3,%2(%0)"
9185   [(set_attr "type" "load")
9186    (set_attr "update" "yes")
9187    (set_attr "indexed" "yes,no")])
9189 (define_insn "movdi_<mode>_update"
9190   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9191                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9192         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9193    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9194         (plus:P (match_dup 1) (match_dup 2)))]
9195   "TARGET_POWERPC64 && TARGET_UPDATE
9196    && (!avoiding_indexed_address_p (DImode)
9197        || !gpc_reg_operand (operands[2], Pmode)
9198        || (REG_P (operands[0])
9199            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9200   "@
9201    stdux %3,%0,%2
9202    stdu %3,%2(%0)"
9203   [(set_attr "type" "store")
9204    (set_attr "update" "yes")
9205    (set_attr "indexed" "yes,no")])
9207 ;; This pattern is only conditional on TARGET_64BIT, as it is
9208 ;; needed for stack allocation, even if the user passes -mno-update.
9209 (define_insn "movdi_update_stack"
9210   [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9211                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9212         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9213    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9214         (plus:DI (match_dup 1) (match_dup 2)))]
9215   "TARGET_64BIT"
9216   "@
9217    stdux %3,%0,%2
9218    stdu %3,%2(%0)"
9219   [(set_attr "type" "store")
9220    (set_attr "update" "yes")
9221    (set_attr "indexed" "yes,no")])
9223 (define_insn "*movsi_update1"
9224   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9225         (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9226                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9227    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9228         (plus:P (match_dup 1) (match_dup 2)))]
9229   "TARGET_UPDATE
9230    && (!avoiding_indexed_address_p (SImode)
9231        || !gpc_reg_operand (operands[2], Pmode))"
9232   "@
9233    lwzux %3,%0,%2
9234    lwzu %3,%2(%0)"
9235   [(set_attr "type" "load")
9236    (set_attr "update" "yes")
9237    (set_attr "indexed" "yes,no")])
9239 (define_insn "*movsi_update2"
9240   [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9241         (sign_extend:EXTSI
9242          (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9243                          (match_operand:P 2 "gpc_reg_operand" "r")))))
9244    (set (match_operand:P 0 "gpc_reg_operand" "=b")
9245         (plus:P (match_dup 1) (match_dup 2)))]
9246   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9247   "lwaux %3,%0,%2"
9248   [(set_attr "type" "load")
9249    (set_attr "sign_extend" "yes")
9250    (set_attr "update" "yes")
9251    (set_attr "indexed" "yes")])
9253 (define_insn "movsi_<mode>_update"
9254   [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9255                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9256         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9257    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9258         (plus:P (match_dup 1) (match_dup 2)))]
9259   "TARGET_UPDATE
9260    && (!avoiding_indexed_address_p (SImode)
9261        || !gpc_reg_operand (operands[2], Pmode)
9262        || (REG_P (operands[0])
9263            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9264   "@
9265    stwux %3,%0,%2
9266    stwu %3,%2(%0)"
9267   [(set_attr "type" "store")
9268    (set_attr "update" "yes")
9269    (set_attr "indexed" "yes,no")])
9271 ;; This is an unconditional pattern; needed for stack allocation, even
9272 ;; if the user passes -mno-update.
9273 (define_insn "movsi_update_stack"
9274   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9275                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9276         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9277    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9278         (plus:SI (match_dup 1) (match_dup 2)))]
9279   "TARGET_32BIT"
9280   "@
9281    stwux %3,%0,%2
9282    stwu %3,%2(%0)"
9283   [(set_attr "type" "store")
9284    (set_attr "update" "yes")
9285    (set_attr "indexed" "yes,no")])
9287 (define_insn "*movhi_update1"
9288   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9289         (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9290                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9291    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9292         (plus:P (match_dup 1) (match_dup 2)))]
9293   "TARGET_UPDATE
9294    && (!avoiding_indexed_address_p (HImode)
9295        || !gpc_reg_operand (operands[2], SImode))"
9296   "@
9297    lhzux %3,%0,%2
9298    lhzu %3,%2(%0)"
9299   [(set_attr "type" "load")
9300    (set_attr "update" "yes")
9301    (set_attr "indexed" "yes,no")])
9303 (define_insn "*movhi_update2"
9304   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9305         (zero_extend:EXTHI
9306          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9307                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9308    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9309         (plus:P (match_dup 1) (match_dup 2)))]
9310   "TARGET_UPDATE
9311    && (!avoiding_indexed_address_p (HImode)
9312        || !gpc_reg_operand (operands[2], Pmode))"
9313   "@
9314    lhzux %3,%0,%2
9315    lhzu %3,%2(%0)"
9316   [(set_attr "type" "load")
9317    (set_attr "update" "yes")
9318    (set_attr "indexed" "yes,no")])
9320 (define_insn "*movhi_update3"
9321   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9322         (sign_extend:EXTHI
9323          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9324                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9325    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9326         (plus:P (match_dup 1) (match_dup 2)))]
9327   "TARGET_UPDATE
9328    && !(avoiding_indexed_address_p (HImode)
9329         && gpc_reg_operand (operands[2], Pmode))"
9330   "@
9331    lhaux %3,%0,%2
9332    lhau %3,%2(%0)"
9333   [(set_attr "type" "load")
9334    (set_attr "sign_extend" "yes")
9335    (set_attr "update" "yes")
9336    (set_attr "indexed" "yes,no")])
9338 (define_insn "*movhi_update4"
9339   [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9340                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9341         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9342    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9343         (plus:P (match_dup 1) (match_dup 2)))]
9344   "TARGET_UPDATE
9345    && (!avoiding_indexed_address_p (HImode)
9346        || !gpc_reg_operand (operands[2], Pmode))"
9347   "@
9348    sthux %3,%0,%2
9349    sthu %3,%2(%0)"
9350   [(set_attr "type" "store")
9351    (set_attr "update" "yes")
9352    (set_attr "indexed" "yes,no")])
9354 (define_insn "*movqi_update1"
9355   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9356         (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9357                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9358    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9359         (plus:P (match_dup 1) (match_dup 2)))]
9360   "TARGET_UPDATE
9361    && (!avoiding_indexed_address_p (QImode)
9362        || !gpc_reg_operand (operands[2], Pmode))"
9363   "@
9364    lbzux %3,%0,%2
9365    lbzu %3,%2(%0)"
9366   [(set_attr "type" "load")
9367    (set_attr "update" "yes")
9368    (set_attr "indexed" "yes,no")])
9370 (define_insn "*movqi_update2"
9371   [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9372         (zero_extend:EXTQI
9373          (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9374                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9375    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9376         (plus:P (match_dup 1) (match_dup 2)))]
9377   "TARGET_UPDATE
9378    && (!avoiding_indexed_address_p (QImode)
9379        || !gpc_reg_operand (operands[2], Pmode))"
9380   "@
9381    lbzux %3,%0,%2
9382    lbzu %3,%2(%0)"
9383   [(set_attr "type" "load")
9384    (set_attr "update" "yes")
9385    (set_attr "indexed" "yes,no")])
9387 (define_insn "*movqi_update3"
9388   [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9389                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9390         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9391    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9392         (plus:P (match_dup 1) (match_dup 2)))]
9393   "TARGET_UPDATE
9394    && (!avoiding_indexed_address_p (QImode)
9395        || !gpc_reg_operand (operands[2], Pmode))"
9396   "@
9397    stbux %3,%0,%2
9398    stbu %3,%2(%0)"
9399   [(set_attr "type" "store")
9400    (set_attr "update" "yes")
9401    (set_attr "indexed" "yes,no")])
9403 (define_insn "*mov<SFDF:mode>_update1"
9404   [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9405         (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9406                           (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9407    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9408         (plus:P (match_dup 1) (match_dup 2)))]
9409   "TARGET_HARD_FLOAT && TARGET_UPDATE
9410    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9411        || !gpc_reg_operand (operands[2], Pmode))"
9412   "@
9413    lf<sd>ux %3,%0,%2
9414    lf<sd>u %3,%2(%0)"
9415   [(set_attr "type" "fpload")
9416    (set_attr "update" "yes")
9417    (set_attr "indexed" "yes,no")
9418    (set_attr "size" "<SFDF:bits>")])
9420 (define_insn "*mov<SFDF:mode>_update2"
9421   [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9422                           (match_operand:P 2 "reg_or_short_operand" "r,I")))
9423         (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9424    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9425         (plus:P (match_dup 1) (match_dup 2)))]
9426   "TARGET_HARD_FLOAT && TARGET_UPDATE
9427    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9428        || !gpc_reg_operand (operands[2], Pmode))"
9429   "@
9430    stf<sd>ux %3,%0,%2
9431    stf<sd>u %3,%2(%0)"
9432   [(set_attr "type" "fpstore")
9433    (set_attr "update" "yes")
9434    (set_attr "indexed" "yes,no")
9435    (set_attr "size" "<SFDF:bits>")])
9437 (define_insn "*movsf_update3"
9438   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9439         (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9440                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9441    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9442         (plus:P (match_dup 1) (match_dup 2)))]
9443   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9444    && (!avoiding_indexed_address_p (SFmode)
9445        || !gpc_reg_operand (operands[2], Pmode))"
9446   "@
9447    lwzux %3,%0,%2
9448    lwzu %3,%2(%0)"
9449   [(set_attr "type" "load")
9450    (set_attr "update" "yes")
9451    (set_attr "indexed" "yes,no")])
9453 (define_insn "*movsf_update4"
9454   [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9455                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9456         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9457    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9458         (plus:P (match_dup 1) (match_dup 2)))]
9459   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9460    && (!avoiding_indexed_address_p (SFmode)
9461        || !gpc_reg_operand (operands[2], Pmode))"
9462   "@
9463    stwux %3,%0,%2
9464    stwu %3,%2(%0)"
9465   [(set_attr "type" "store")
9466    (set_attr "update" "yes")
9467    (set_attr "indexed" "yes,no")])
9470 ;; After inserting conditional returns we can sometimes have
9471 ;; unnecessary register moves.  Unfortunately we cannot have a
9472 ;; modeless peephole here, because some single SImode sets have early
9473 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9474 ;; sequences, using get_attr_length here will smash the operands
9475 ;; array.  Neither is there an early_cobbler_p predicate.
9476 ;; Also this optimization interferes with scalars going into
9477 ;; altivec registers (the code does reloading through the FPRs).
9478 (define_peephole2
9479   [(set (match_operand:DF 0 "gpc_reg_operand")
9480         (match_operand:DF 1 "any_operand"))
9481    (set (match_operand:DF 2 "gpc_reg_operand")
9482         (match_dup 0))]
9483   "!TARGET_VSX
9484    && peep2_reg_dead_p (2, operands[0])"
9485   [(set (match_dup 2) (match_dup 1))])
9487 (define_peephole2
9488   [(set (match_operand:SF 0 "gpc_reg_operand")
9489         (match_operand:SF 1 "any_operand"))
9490    (set (match_operand:SF 2 "gpc_reg_operand")
9491         (match_dup 0))]
9492   "!TARGET_P8_VECTOR
9493    && peep2_reg_dead_p (2, operands[0])"
9494   [(set (match_dup 2) (match_dup 1))])
9497 ;; TLS support.
9499 (define_insn "*tls_gd_pcrel<bits>"
9500   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9501         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9502                    (const_int 0)]
9503                   UNSPEC_TLSGD))]
9504   "HAVE_AS_TLS && TARGET_ELF"
9505   "la %0,%1@got@tlsgd@pcrel"
9506   [(set_attr "prefixed" "yes")])
9508 (define_insn_and_split "*tls_gd<bits>"
9509   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9510         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9511                    (match_operand:P 2 "gpc_reg_operand" "b")]
9512                   UNSPEC_TLSGD))]
9513   "HAVE_AS_TLS && TARGET_ELF"
9514   "addi %0,%2,%1@got@tlsgd"
9515   "&& TARGET_CMODEL != CMODEL_SMALL"
9516   [(set (match_dup 3)
9517         (high:P
9518             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9519    (set (match_dup 0)
9520         (lo_sum:P (match_dup 3)
9521             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9523   operands[3] = gen_reg_rtx (<MODE>mode);
9525   [(set (attr "length")
9526      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9527                    (const_int 8)
9528                    (const_int 4)))])
9530 (define_insn "*tls_gd_high<bits>"
9531   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9532      (high:P
9533        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9534                   (match_operand:P 2 "gpc_reg_operand" "b")]
9535                  UNSPEC_TLSGD)))]
9536   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9537   "addis %0,%2,%1@got@tlsgd@ha")
9539 (define_insn "*tls_gd_low<bits>"
9540   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9541      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9542        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9543                   (match_operand:P 3 "gpc_reg_operand" "b")]
9544                  UNSPEC_TLSGD)))]
9545   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9546   "addi %0,%1,%2@got@tlsgd@l")
9548 (define_insn "*tls_ld_pcrel<bits>"
9549   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9550         (unspec:P [(const_int 0)]
9551                   UNSPEC_TLSLD))]
9552   "HAVE_AS_TLS && TARGET_ELF"
9553   "la %0,%&@got@tlsld@pcrel"
9554   [(set_attr "prefixed" "yes")])
9556 (define_insn_and_split "*tls_ld<bits>"
9557   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9558         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9559                   UNSPEC_TLSLD))]
9560   "HAVE_AS_TLS && TARGET_ELF"
9561   "addi %0,%1,%&@got@tlsld"
9562   "&& TARGET_CMODEL != CMODEL_SMALL"
9563   [(set (match_dup 2)
9564         (high:P
9565             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9566    (set (match_dup 0)
9567         (lo_sum:P (match_dup 2)
9568             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9570   operands[2] = gen_reg_rtx (<MODE>mode);
9572   [(set (attr "length")
9573      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9574                    (const_int 8)
9575                    (const_int 4)))])
9577 (define_insn "*tls_ld_high<bits>"
9578   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9579      (high:P
9580        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9581                  UNSPEC_TLSLD)))]
9582   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9583   "addis %0,%1,%&@got@tlsld@ha")
9585 (define_insn "*tls_ld_low<bits>"
9586   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9587      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9588        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9589                  UNSPEC_TLSLD)))]
9590   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9591   "addi %0,%1,%&@got@tlsld@l")
9593 (define_insn "tls_dtprel_<bits>"
9594   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9595         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9596                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9597                   UNSPEC_TLSDTPREL))]
9598   "HAVE_AS_TLS"
9599   "addi %0,%1,%2@dtprel"
9600   [(set (attr "prefixed")
9601         (if_then_else (match_test "rs6000_tls_size == 16")
9602                       (const_string "no")
9603                       (const_string "yes")))])
9605 (define_insn "tls_dtprel_ha_<bits>"
9606   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9607         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9608                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9609                   UNSPEC_TLSDTPRELHA))]
9610   "HAVE_AS_TLS"
9611   "addis %0,%1,%2@dtprel@ha")
9613 (define_insn "tls_dtprel_lo_<bits>"
9614   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9615         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9616                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9617                   UNSPEC_TLSDTPRELLO))]
9618   "HAVE_AS_TLS"
9619   "addi %0,%1,%2@dtprel@l")
9621 (define_insn_and_split "tls_got_dtprel_<bits>"
9622   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9623         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9624                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9625                   UNSPEC_TLSGOTDTPREL))]
9626   "HAVE_AS_TLS"
9627   "<ptrload> %0,%2@got@dtprel(%1)"
9628   "&& TARGET_CMODEL != CMODEL_SMALL"
9629   [(set (match_dup 3)
9630         (high:P
9631             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9632    (set (match_dup 0)
9633         (lo_sum:P (match_dup 3)
9634             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9636   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9638   [(set (attr "length")
9639      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9640                    (const_int 8)
9641                    (const_int 4)))])
9643 (define_insn "*tls_got_dtprel_high<bits>"
9644   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9645      (high:P
9646        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9647                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9648                  UNSPEC_TLSGOTDTPREL)))]
9649   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9650   "addis %0,%1,%2@got@dtprel@ha")
9652 (define_insn "*tls_got_dtprel_low<bits>"
9653   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9654      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9655          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9656                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9657                    UNSPEC_TLSGOTDTPREL)))]
9658   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9659   "<ptrload> %0,%2@got@dtprel@l(%1)")
9661 (define_insn "tls_tprel_<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_TLSTPREL))]
9666   "HAVE_AS_TLS"
9667   "addi %0,%1,%2@tprel"
9668   [(set (attr "prefixed")
9669         (if_then_else (match_test "rs6000_tls_size == 16")
9670                       (const_string "no")
9671                       (const_string "yes")))])
9673 (define_insn "tls_tprel_ha_<bits>"
9674   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9675         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9676                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9677                   UNSPEC_TLSTPRELHA))]
9678   "HAVE_AS_TLS"
9679   "addis %0,%1,%2@tprel@ha")
9681 (define_insn "tls_tprel_lo_<bits>"
9682   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9683         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9684                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9685                   UNSPEC_TLSTPRELLO))]
9686   "HAVE_AS_TLS"
9687   "addi %0,%1,%2@tprel@l")
9689 (define_insn "*tls_got_tprel_pcrel_<bits>"
9690   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9691         (unspec:P [(const_int 0)
9692                    (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9693                   UNSPEC_TLSGOTTPREL))]
9694   "HAVE_AS_TLS"
9695   "<ptrload> %0,%1@got@tprel@pcrel"
9696   [(set_attr "prefixed" "yes")])
9698 ;; "b" output constraint here and on tls_tls input to support linker tls
9699 ;; optimization.  The linker may edit the instructions emitted by a
9700 ;; tls_got_tprel/tls_tls pair to addis,addi.
9701 (define_insn_and_split "tls_got_tprel_<bits>"
9702   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9703         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9704                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9705                   UNSPEC_TLSGOTTPREL))]
9706   "HAVE_AS_TLS"
9707   "<ptrload> %0,%2@got@tprel(%1)"
9708   "&& TARGET_CMODEL != CMODEL_SMALL"
9709   [(set (match_dup 3)
9710         (high:P
9711             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9712    (set (match_dup 0)
9713         (lo_sum:P (match_dup 3)
9714             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9716   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9718   [(set (attr "length")
9719      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9720                    (const_int 8)
9721                    (const_int 4)))])
9723 (define_insn "*tls_got_tprel_high<bits>"
9724   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9725      (high:P
9726        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9727                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9728                  UNSPEC_TLSGOTTPREL)))]
9729   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9730   "addis %0,%1,%2@got@tprel@ha")
9732 (define_insn "*tls_got_tprel_low<bits>"
9733   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9734      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9735          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9736                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9737                    UNSPEC_TLSGOTTPREL)))]
9738   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9739   "<ptrload> %0,%2@got@tprel@l(%1)")
9741 (define_insn "tls_tls_pcrel_<bits>"
9742   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9743         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9744                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9745                   UNSPEC_TLSTLS_PCREL))]
9746   "TARGET_ELF && HAVE_AS_TLS"
9747   "add %0,%1,%2@tls@pcrel")
9749 (define_insn "tls_tls_<bits>"
9750   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9751         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9752                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9753                   UNSPEC_TLSTLS))]
9754   "TARGET_ELF && HAVE_AS_TLS"
9755   "add %0,%1,%2@tls")
9757 (define_expand "tls_get_tpointer"
9758   [(set (match_operand:SI 0 "gpc_reg_operand")
9759         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9760   "TARGET_XCOFF && HAVE_AS_TLS"
9762   emit_insn (gen_tls_get_tpointer_internal ());
9763   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9764   DONE;
9767 (define_insn "tls_get_tpointer_internal"
9768   [(set (reg:SI 3)
9769         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9770    (clobber (reg:SI LR_REGNO))]
9771   "TARGET_XCOFF && HAVE_AS_TLS"
9772   "bla __get_tpointer")
9774 (define_expand "tls_get_addr<mode>"
9775   [(set (match_operand:P 0 "gpc_reg_operand")
9776         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9777                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9778   "TARGET_XCOFF && HAVE_AS_TLS"
9780   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9781   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9782   emit_insn (gen_tls_get_addr_internal<mode> ());
9783   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9784   DONE;
9787 (define_insn "tls_get_addr_internal<mode>"
9788   [(set (reg:P 3)
9789         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9790    (clobber (reg:P 0))
9791    (clobber (reg:P 4))
9792    (clobber (reg:P 5))
9793    (clobber (reg:P 11))
9794    (clobber (reg:CC CR0_REGNO))
9795    (clobber (reg:P LR_REGNO))]
9796   "TARGET_XCOFF && HAVE_AS_TLS"
9797   "bla __tls_get_addr")
9799 ;; Next come insns related to the calling sequence.
9801 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9802 ;; We move the back-chain and decrement the stack pointer.
9804 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9805 ;; constant alloca, using that predicate will force the generic code to put
9806 ;; the constant size into a register before calling the expander.
9808 ;; As a result the expander would not have the constant size information
9809 ;; in those cases and would have to generate less efficient code.
9811 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9812 ;; the constant size.  The value is forced into a register if necessary.
9814 (define_expand "allocate_stack"
9815   [(set (match_operand 0 "gpc_reg_operand")
9816         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9817    (set (reg 1)
9818         (minus (reg 1) (match_dup 1)))]
9819   ""
9821   rtx chain = gen_reg_rtx (Pmode);
9822   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9823   rtx neg_op0;
9824   rtx insn, par, set, mem;
9826   /* By allowing reg_or_cint_operand as the predicate we can get
9827      better code for stack-clash-protection because we do not lose
9828      size information.  But the rest of the code expects the operand
9829      to be reg_or_short_operand.  If it isn't, then force it into
9830      a register.  */
9831   rtx orig_op1 = operands[1];
9832   if (!reg_or_short_operand (operands[1], Pmode))
9833     operands[1] = force_reg (Pmode, operands[1]);
9835   emit_move_insn (chain, stack_bot);
9837   /* Check stack bounds if necessary.  */
9838   if (crtl->limit_stack)
9839     {
9840       rtx available;
9841       available = expand_binop (Pmode, sub_optab,
9842                                 stack_pointer_rtx, stack_limit_rtx,
9843                                 NULL_RTX, 1, OPTAB_WIDEN);
9844       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9845     }
9847   /* Allocate and probe if requested.
9848      This may look similar to the loop we use for prologue allocations,
9849      but it is critically different.  For the former we know the loop
9850      will iterate, but do not know that generally here.  The former
9851      uses that knowledge to rotate the loop.  Combining them would be
9852      possible with some performance cost.  */
9853   if (flag_stack_clash_protection)
9854     {
9855       rtx rounded_size, last_addr, residual;
9856       HOST_WIDE_INT probe_interval;
9857       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9858                                                 &residual, &probe_interval,
9859                                                 orig_op1);
9860       
9861       /* We do occasionally get in here with constant sizes, we might
9862          as well do a reasonable job when we obviously can.  */
9863       if (rounded_size != const0_rtx)
9864         {
9865           rtx loop_lab, end_loop;
9866           bool rotated = CONST_INT_P (rounded_size);
9867           rtx update = GEN_INT (-probe_interval);
9868           if (probe_interval > 32768)
9869             update = force_reg (Pmode, update);
9871           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9872                                                         last_addr, rotated);
9874           if (TARGET_32BIT)
9875             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9876                                                stack_pointer_rtx,
9877                                                update, chain));
9878           else
9879             emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9880                                                stack_pointer_rtx,
9881                                                update, chain));
9882           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9883                                                       last_addr, rotated);
9884         }
9886       /* Now handle residuals.  We just have to set operands[1] correctly
9887          and let the rest of the expander run.  */
9888       operands[1] = residual;
9889     }
9891   if (!(CONST_INT_P (operands[1])
9892         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9893     {
9894       operands[1] = force_reg (Pmode, operands[1]);
9895       neg_op0 = gen_reg_rtx (Pmode);
9896       emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9897     }
9898   else
9899     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9901   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9902                                        : gen_movdi_update_stack))
9903                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9904                          chain));
9905   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9906      it now and set the alias set/attributes. The above gen_*_update
9907      calls will generate a PARALLEL with the MEM set being the first
9908      operation. */
9909   par = PATTERN (insn);
9910   gcc_assert (GET_CODE (par) == PARALLEL);
9911   set = XVECEXP (par, 0, 0);
9912   gcc_assert (GET_CODE (set) == SET);
9913   mem = SET_DEST (set);
9914   gcc_assert (MEM_P (mem));
9915   MEM_NOTRAP_P (mem) = 1;
9916   set_mem_alias_set (mem, get_frame_alias_set ());
9918   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9919   DONE;
9922 ;; These patterns say how to save and restore the stack pointer.  We need not
9923 ;; save the stack pointer at function level since we are careful to
9924 ;; preserve the backchain.  At block level, we have to restore the backchain
9925 ;; when we restore the stack pointer.
9927 ;; For nonlocal gotos, we must save both the stack pointer and its
9928 ;; backchain and restore both.  Note that in the nonlocal case, the
9929 ;; save area is a memory location.
9931 (define_expand "save_stack_function"
9932   [(match_operand 0 "any_operand")
9933    (match_operand 1 "any_operand")]
9934   ""
9935   "DONE;")
9937 (define_expand "restore_stack_function"
9938   [(match_operand 0 "any_operand")
9939    (match_operand 1 "any_operand")]
9940   ""
9941   "DONE;")
9943 ;; Adjust stack pointer (op0) to a new value (op1).
9944 ;; First copy old stack backchain to new location, and ensure that the
9945 ;; scheduler won't reorder the sp assignment before the backchain write.
9946 (define_expand "restore_stack_block"
9947   [(set (match_dup 2) (match_dup 3))
9948    (set (match_dup 4) (match_dup 2))
9949    (match_dup 5)
9950    (set (match_operand 0 "register_operand")
9951         (match_operand 1 "register_operand"))]
9952   ""
9954   rtvec p;
9956   operands[1] = force_reg (Pmode, operands[1]);
9957   operands[2] = gen_reg_rtx (Pmode);
9958   operands[3] = gen_frame_mem (Pmode, operands[0]);
9959   operands[4] = gen_frame_mem (Pmode, operands[1]);
9960   p = rtvec_alloc (1);
9961   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9962                                   const0_rtx);
9963   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9966 (define_expand "save_stack_nonlocal"
9967   [(set (match_dup 3) (match_dup 4))
9968    (set (match_operand 0 "memory_operand") (match_dup 3))
9969    (set (match_dup 2) (match_operand 1 "register_operand"))]
9970   ""
9972   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9974   /* Copy the backchain to the first word, sp to the second.  */
9975   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9976   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9977   operands[3] = gen_reg_rtx (Pmode);
9978   operands[4] = gen_frame_mem (Pmode, operands[1]);
9981 (define_expand "restore_stack_nonlocal"
9982   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9983    (set (match_dup 3) (match_dup 4))
9984    (set (match_dup 5) (match_dup 2))
9985    (match_dup 6)
9986    (set (match_operand 0 "register_operand") (match_dup 3))]
9987   ""
9989   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9990   rtvec p;
9992   /* Restore the backchain from the first word, sp from the second.  */
9993   operands[2] = gen_reg_rtx (Pmode);
9994   operands[3] = gen_reg_rtx (Pmode);
9995   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9996   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9997   operands[5] = gen_frame_mem (Pmode, operands[3]);
9998   p = rtvec_alloc (1);
9999   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10000                                   const0_rtx);
10001   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10004 ;; Load up a PC-relative address.  Print_operand_address will append a @pcrel
10005 ;; to the symbol or label.
10006 (define_insn "*pcrel_local_addr"
10007   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10008         (match_operand:DI 1 "pcrel_local_address"))]
10009   "TARGET_PCREL"
10010   "la %0,%a1"
10011   [(set_attr "prefixed" "yes")])
10013 ;; Load up a PC-relative address to an external symbol.  If the symbol and the
10014 ;; program are both defined in the main program, the linker will optimize this
10015 ;; to a PADDI.  Otherwise, it will create a GOT address that is relocated by
10016 ;; the dynamic linker and loaded up.  Print_operand_address will append a
10017 ;; @got@pcrel to the symbol.
10018 (define_insn "*pcrel_extern_addr"
10019   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10020         (match_operand:DI 1 "pcrel_external_address"))]
10021   "TARGET_PCREL"
10022   "ld %0,%a1"
10023   [(set_attr "prefixed" "yes")
10024    (set_attr "type" "load")])
10026 ;; TOC register handling.
10028 ;; Code to initialize the TOC register...
10030 (define_insn "load_toc_aix_si"
10031   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10032                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10033               (use (reg:SI 2))])]
10034   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10036   char buf[30];
10037   extern int need_toc_init;
10038   need_toc_init = 1;
10039   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10040   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10041   operands[2] = gen_rtx_REG (Pmode, 2);
10042   return "lwz %0,%1(%2)";
10044   [(set_attr "type" "load")
10045    (set_attr "update" "no")
10046    (set_attr "indexed" "no")])
10048 (define_insn "load_toc_aix_di"
10049   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10050                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10051               (use (reg:DI 2))])]
10052   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10054   char buf[30];
10055   extern int need_toc_init;
10056   need_toc_init = 1;
10057   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10058                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10059   if (TARGET_ELF)
10060     strcat (buf, "@toc");
10061   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10062   operands[2] = gen_rtx_REG (Pmode, 2);
10063   return "ld %0,%1(%2)";
10065   [(set_attr "type" "load")
10066    (set_attr "update" "no")
10067    (set_attr "indexed" "no")])
10069 (define_insn "load_toc_v4_pic_si"
10070   [(set (reg:SI LR_REGNO)
10071         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10072   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10073   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10074   [(set_attr "type" "branch")])
10076 (define_expand "load_toc_v4_PIC_1"
10077   [(parallel [(set (reg:SI LR_REGNO)
10078                    (match_operand:SI 0 "immediate_operand" "s"))
10079               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10080   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10081    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10082   "")
10084 (define_insn "load_toc_v4_PIC_1_normal"
10085   [(set (reg:SI LR_REGNO)
10086         (match_operand:SI 0 "immediate_operand" "s"))
10087    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10088   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10089    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10090   "bcl 20,31,%0\n%0:"
10091   [(set_attr "type" "branch")
10092    (set_attr "cannot_copy" "yes")])
10094 (define_insn "load_toc_v4_PIC_1_476"
10095   [(set (reg:SI LR_REGNO)
10096         (match_operand:SI 0 "immediate_operand" "s"))
10097    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10098   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10099    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10101   char name[32];
10102   static char templ[32];
10104   get_ppc476_thunk_name (name);
10105   sprintf (templ, "bl %s\n%%0:", name);
10106   return templ;
10108   [(set_attr "type" "branch")
10109    (set_attr "cannot_copy" "yes")])
10111 (define_expand "load_toc_v4_PIC_1b"
10112   [(parallel [(set (reg:SI LR_REGNO)
10113                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10114                                (label_ref (match_operand 1 ""))]
10115                            UNSPEC_TOCPTR))
10116               (match_dup 1)])]
10117   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10118   "")
10120 (define_insn "load_toc_v4_PIC_1b_normal"
10121   [(set (reg:SI LR_REGNO)
10122         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10123                     (label_ref (match_operand 1 "" ""))]
10124                 UNSPEC_TOCPTR))
10125    (match_dup 1)]
10126   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10127   "bcl 20,31,$+8\;.long %0-$"
10128   [(set_attr "type" "branch")
10129    (set_attr "length" "8")])
10131 (define_insn "load_toc_v4_PIC_1b_476"
10132   [(set (reg:SI LR_REGNO)
10133         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10134                     (label_ref (match_operand 1 "" ""))]
10135                 UNSPEC_TOCPTR))
10136    (match_dup 1)]
10137   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10139   char name[32];
10140   static char templ[32];
10142   get_ppc476_thunk_name (name);
10143   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10144   return templ;
10146   [(set_attr "type" "branch")
10147    (set_attr "length" "16")])
10149 (define_insn "load_toc_v4_PIC_2"
10150   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10151         (mem:SI (plus:SI
10152                   (match_operand:SI 1 "gpc_reg_operand" "b")
10153                   (const
10154                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10155                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10156   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10157   "lwz %0,%2-%3(%1)"
10158   [(set_attr "type" "load")])
10160 (define_insn "load_toc_v4_PIC_3b"
10161   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10162         (plus:SI
10163           (match_operand:SI 1 "gpc_reg_operand" "b")
10164           (high:SI
10165             (const
10166               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10167                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10168   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10169   "addis %0,%1,%2-%3@ha")
10171 (define_insn "load_toc_v4_PIC_3c"
10172   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10173         (lo_sum:SI
10174           (match_operand:SI 1 "gpc_reg_operand" "b")
10175           (const
10176             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10177                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10178   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10179   "addi %0,%1,%2-%3@l")
10181 ;; If the TOC is shared over a translation unit, as happens with all
10182 ;; the kinds of PIC that we support, we need to restore the TOC
10183 ;; pointer only when jumping over units of translation.
10184 ;; On Darwin, we need to reload the picbase.
10186 (define_expand "builtin_setjmp_receiver"
10187   [(use (label_ref (match_operand 0 "")))]
10188   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10189    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10190    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10192 #if TARGET_MACHO
10193   if (DEFAULT_ABI == ABI_DARWIN)
10194     {
10195       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10196       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10197       rtx tmplabrtx;
10198       char tmplab[20];
10200       crtl->uses_pic_offset_table = 1;
10201       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10202                                   CODE_LABEL_NUMBER (operands[0]));
10203       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10205       emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10206       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10207       emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10208                                         picrtx, tmplabrtx));
10209     }
10210   else
10211 #endif
10212     rs6000_emit_load_toc_table (FALSE);
10213   DONE;
10216 ;; Largetoc support
10217 (define_insn "*largetoc_high"
10218   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10219         (high:DI
10220           (unspec [(match_operand:DI 1 "" "")
10221                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10222                   UNSPEC_TOCREL)))]
10223    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10224    "addis %0,%2,%1@toc@ha")
10226 (define_insn "*largetoc_high_aix<mode>"
10227   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10228         (high:P
10229           (unspec [(match_operand:P 1 "" "")
10230                    (match_operand:P 2 "gpc_reg_operand" "b")]
10231                   UNSPEC_TOCREL)))]
10232    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10233    "addis %0,%1@u(%2)")
10235 (define_insn "*largetoc_high_plus"
10236   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10237         (high:DI
10238           (plus:DI
10239             (unspec [(match_operand:DI 1 "" "")
10240                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10241                     UNSPEC_TOCREL)
10242             (match_operand:DI 3 "add_cint_operand" "n"))))]
10243    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10244    "addis %0,%2,%1+%3@toc@ha")
10246 (define_insn "*largetoc_high_plus_aix<mode>"
10247   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10248         (high:P
10249           (plus:P
10250             (unspec [(match_operand:P 1 "" "")
10251                      (match_operand:P 2 "gpc_reg_operand" "b")]
10252                     UNSPEC_TOCREL)
10253             (match_operand:P 3 "add_cint_operand" "n"))))]
10254    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10255    "addis %0,%1+%3@u(%2)")
10257 (define_insn "*largetoc_low"
10258   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10259         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10260                    (match_operand:DI 2 "" "")))]
10261    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10262    "addi %0,%1,%2@l")
10264 (define_insn "*largetoc_low_aix<mode>"
10265   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10266         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10267                    (match_operand:P 2 "" "")))]
10268    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10269    "la %0,%2@l(%1)")
10271 (define_insn_and_split "*tocref<mode>"
10272   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10273         (match_operand:P 1 "small_toc_ref" "R"))]
10274    "TARGET_TOC"
10275    "la %0,%a1"
10276    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10277   [(set (match_dup 0) (high:P (match_dup 1)))
10278    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10280 ;; Elf specific ways of loading addresses for non-PIC code.
10281 ;; The output of this could be r0, but we make a very strong
10282 ;; preference for a base register because it will usually
10283 ;; be needed there.
10284 (define_insn "elf_high"
10285   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10286         (high:SI (match_operand 1 "" "")))]
10287   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10288   "lis %0,%1@ha")
10290 (define_insn "elf_low"
10291   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10292         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10293                    (match_operand 2 "" "")))]
10294    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10295    "la %0,%2@l(%1)")
10297 (define_insn "*pltseq_tocsave_<mode>"
10298   [(set (match_operand:P 0 "memory_operand" "=m")
10299         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10300                    (match_operand:P 2 "symbol_ref_operand" "s")
10301                    (match_operand:P 3 "" "")]
10302                   UNSPEC_PLTSEQ))]
10303   "TARGET_PLTSEQ
10304    && DEFAULT_ABI == ABI_ELFv2"
10306   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10309 (define_insn "*pltseq_plt16_ha_<mode>"
10310   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10311         (unspec:P [(match_operand:P 1 "" "")
10312                    (match_operand:P 2 "symbol_ref_operand" "s")
10313                    (match_operand:P 3 "" "")]
10314                   UNSPEC_PLT16_HA))]
10315   "TARGET_PLTSEQ"
10317   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10320 (define_insn "*pltseq_plt16_lo_<mode>"
10321   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10322         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10323                    (match_operand:P 2 "symbol_ref_operand" "s")
10324                    (match_operand:P 3 "" "")]
10325                   UNSPEC_PLT16_LO))]
10326   "TARGET_PLTSEQ"
10328   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10330   [(set_attr "type" "load")])
10332 (define_insn "*pltseq_mtctr_<mode>"
10333   [(set (match_operand:P 0 "register_operand" "=c")
10334         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10335                    (match_operand:P 2 "symbol_ref_operand" "s")
10336                    (match_operand:P 3 "" "")]
10337                   UNSPEC_PLTSEQ))]
10338   "TARGET_PLTSEQ"
10340   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10343 (define_insn "*pltseq_plt_pcrel<mode>"
10344   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10345         (unspec:P [(match_operand:P 1 "" "")
10346                    (match_operand:P 2 "symbol_ref_operand" "s")
10347                    (match_operand:P 3 "" "")]
10348                   UNSPEC_PLT_PCREL))]
10349   "HAVE_AS_PLTSEQ && TARGET_ELF
10350    && rs6000_pcrel_p (cfun)"
10352   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10354   [(set_attr "type" "load")
10355    (set_attr "length" "12")])
10357 ;; Call and call_value insns
10358 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10359 (define_expand "call"
10360   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10361                     (match_operand 1 ""))
10362               (use (match_operand 2 ""))
10363               (clobber (reg:SI LR_REGNO))])]
10364   ""
10366 #if TARGET_MACHO
10367   if (MACHOPIC_INDIRECT)
10368     operands[0] = machopic_indirect_call_target (operands[0]);
10369 #endif
10371   gcc_assert (MEM_P (operands[0]));
10373   operands[0] = XEXP (operands[0], 0);
10375   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10376     rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10377   else if (DEFAULT_ABI == ABI_V4)
10378     rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10379   else if (DEFAULT_ABI == ABI_DARWIN)
10380     rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10381   else
10382     gcc_unreachable ();
10384   DONE;
10387 (define_expand "call_value"
10388   [(parallel [(set (match_operand 0 "")
10389                    (call (mem:SI (match_operand 1 "address_operand"))
10390                          (match_operand 2 "")))
10391               (use (match_operand 3 ""))
10392               (clobber (reg:SI LR_REGNO))])]
10393   ""
10395 #if TARGET_MACHO
10396   if (MACHOPIC_INDIRECT)
10397     operands[1] = machopic_indirect_call_target (operands[1]);
10398 #endif
10400   gcc_assert (MEM_P (operands[1]));
10402   operands[1] = XEXP (operands[1], 0);
10404   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10405     rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10406   else if (DEFAULT_ABI == ABI_V4)
10407     rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10408   else if (DEFAULT_ABI == ABI_DARWIN)
10409     rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10410   else
10411     gcc_unreachable ();
10413   DONE;
10416 ;; Call to function in current module.  No TOC pointer reload needed.
10417 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10418 ;; either the function was not prototyped, or it was prototyped as a
10419 ;; variable argument function.  It is > 0 if FP registers were passed
10420 ;; and < 0 if they were not.
10422 (define_insn "*call_local32"
10423   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10424          (match_operand 1))
10425    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10426    (clobber (reg:SI LR_REGNO))]
10427   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10429   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10430     output_asm_insn ("crxor 6,6,6", operands);
10432   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10433     output_asm_insn ("creqv 6,6,6", operands);
10435   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10437   [(set_attr "type" "branch")
10438    (set_attr "length" "4,8")])
10440 (define_insn "*call_local64"
10441   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10442          (match_operand 1))
10443    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10444    (clobber (reg:DI LR_REGNO))]
10445   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10447   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10448     output_asm_insn ("crxor 6,6,6", operands);
10450   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10451     output_asm_insn ("creqv 6,6,6", operands);
10453   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10455   [(set_attr "type" "branch")
10456    (set_attr "length" "4,8")])
10458 (define_insn "*call_value_local32"
10459   [(set (match_operand 0 "" "")
10460         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10461               (match_operand 2)))
10462    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10463    (clobber (reg:SI LR_REGNO))]
10464   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10466   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10467     output_asm_insn ("crxor 6,6,6", operands);
10469   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10470     output_asm_insn ("creqv 6,6,6", operands);
10472   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10474   [(set_attr "type" "branch")
10475    (set_attr "length" "4,8")])
10478 (define_insn "*call_value_local64"
10479   [(set (match_operand 0 "" "")
10480         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10481               (match_operand 2)))
10482    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10483    (clobber (reg:DI LR_REGNO))]
10484   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10486   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10487     output_asm_insn ("crxor 6,6,6", operands);
10489   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10490     output_asm_insn ("creqv 6,6,6", operands);
10492   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10494   [(set_attr "type" "branch")
10495    (set_attr "length" "4,8")])
10498 ;; A function pointer under System V is just a normal pointer
10499 ;; operands[0] is the function pointer
10500 ;; operands[1] is the tls call arg
10501 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10502 ;; which indicates how to set cr1
10504 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10505   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10506          (match_operand 1))
10507    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10508    (clobber (reg:P LR_REGNO))]
10509   "DEFAULT_ABI == ABI_V4
10510    || DEFAULT_ABI == ABI_DARWIN"
10512   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10513     output_asm_insn ("crxor 6,6,6", operands);
10515   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10516     output_asm_insn ("creqv 6,6,6", operands);
10518   return rs6000_indirect_call_template (operands, 0);
10520   [(set_attr "type" "jmpreg")
10521    (set (attr "length")
10522         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10523                          (match_test "which_alternative != 1"))
10524                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10525                   (const_string "12")
10526                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10527                          (match_test "which_alternative != 1"))
10528                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10529                   (const_string "8")]
10530               (const_string "4")))])
10532 (define_insn "*call_nonlocal_sysv<mode>"
10533   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10534          (match_operand 1))
10535    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10536    (clobber (reg:P LR_REGNO))]
10537   "(DEFAULT_ABI == ABI_DARWIN
10538    || (DEFAULT_ABI == ABI_V4
10539        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10541   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10542     output_asm_insn ("crxor 6,6,6", operands);
10544   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10545     output_asm_insn ("creqv 6,6,6", operands);
10547   return rs6000_call_template (operands, 0);
10549   [(set_attr "type" "branch,branch")
10550    (set_attr "length" "4,8")])
10552 (define_insn "*call_nonlocal_sysv_secure<mode>"
10553   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10554          (match_operand 1))
10555    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10556    (use (match_operand:SI 3 "register_operand" "r,r"))
10557    (clobber (reg:P LR_REGNO))]
10558   "(DEFAULT_ABI == ABI_V4
10559     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10560     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10562   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10563     output_asm_insn ("crxor 6,6,6", operands);
10565   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10566     output_asm_insn ("creqv 6,6,6", operands);
10568   return rs6000_call_template (operands, 0);
10570   [(set_attr "type" "branch,branch")
10571    (set_attr "length" "4,8")])
10573 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10574   [(set (match_operand 0 "" "")
10575         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10576               (match_operand:P 2 "unspec_tls" "")))
10577    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10578    (clobber (reg:P LR_REGNO))]
10579   "DEFAULT_ABI == ABI_V4
10580    || DEFAULT_ABI == ABI_DARWIN"
10582   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10583     output_asm_insn ("crxor 6,6,6", operands);
10585   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10586     output_asm_insn ("creqv 6,6,6", operands);
10588   return rs6000_indirect_call_template (operands, 1);
10590   [(set_attr "type" "jmpreg")
10591    (set (attr "length")
10592         (plus
10593           (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10594             (const_int 4)
10595             (const_int 0))
10596           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10597                              (match_test "which_alternative != 1"))
10598             (const_int 8)
10599             (const_int 4))))])
10601 (define_insn "*call_value_nonlocal_sysv<mode>"
10602   [(set (match_operand 0 "" "")
10603         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10604               (match_operand:P 2 "unspec_tls" "")))
10605    (use (match_operand:SI 3 "immediate_operand" "n"))
10606    (clobber (reg:P LR_REGNO))]
10607   "(DEFAULT_ABI == ABI_DARWIN
10608     || (DEFAULT_ABI == ABI_V4
10609         && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10611   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10612     output_asm_insn ("crxor 6,6,6", operands);
10614   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10615     output_asm_insn ("creqv 6,6,6", operands);
10617   return rs6000_call_template (operands, 1);
10619   [(set_attr "type" "branch")
10620    (set (attr "length")
10621         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10622           (const_int 8)
10623           (const_int 4)))])
10625 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10626   [(set (match_operand 0 "" "")
10627         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10628               (match_operand:P 2 "unspec_tls" "")))
10629    (use (match_operand:SI 3 "immediate_operand" "n"))
10630    (use (match_operand:SI 4 "register_operand" "r"))
10631    (clobber (reg:P LR_REGNO))]
10632   "(DEFAULT_ABI == ABI_V4
10633     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10634     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10636   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10637     output_asm_insn ("crxor 6,6,6", operands);
10639   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10640     output_asm_insn ("creqv 6,6,6", operands);
10642   return rs6000_call_template (operands, 1);
10644   [(set_attr "type" "branch")
10645    (set (attr "length")
10646         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10647           (const_int 8)
10648           (const_int 4)))])
10650 ;; Call to AIX abi function in the same module.
10652 (define_insn "*call_local_aix<mode>"
10653   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10654          (match_operand 1))
10655    (clobber (reg:P LR_REGNO))]
10656   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10658   if (rs6000_pcrel_p (cfun))
10659     return "bl %z0@notoc";
10660   return "bl %z0";
10662   [(set_attr "type" "branch")])
10664 (define_insn "*call_value_local_aix<mode>"
10665   [(set (match_operand 0 "" "")
10666         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10667               (match_operand 2)))
10668    (clobber (reg:P LR_REGNO))]
10669   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10671   if (rs6000_pcrel_p (cfun))
10672     return "bl %z1@notoc";
10673   return "bl %z1";
10675   [(set_attr "type" "branch")])
10677 ;; Call to AIX abi function which may be in another module.
10678 ;; Restore the TOC pointer (r2) after the call.
10680 (define_insn "*call_nonlocal_aix<mode>"
10681   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10682          (match_operand 1))
10683    (clobber (reg:P LR_REGNO))]
10684   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10686   return rs6000_call_template (operands, 0);
10688   [(set_attr "type" "branch")
10689    (set (attr "length")
10690         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10691           (const_int 4)
10692           (const_int 8)))])
10694 (define_insn "*call_value_nonlocal_aix<mode>"
10695   [(set (match_operand 0 "" "")
10696         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10697               (match_operand:P 2 "unspec_tls" "")))
10698    (clobber (reg:P LR_REGNO))]
10699   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10701   return rs6000_call_template (operands, 1);
10703   [(set_attr "type" "branch")
10704    (set (attr "length")
10705         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10706             (const_int 4)
10707             (const_int 8)))])
10709 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10710 ;; Operand0 is the addresss of the function to call
10711 ;; Operand2 is the location in the function descriptor to load r2 from
10712 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10714 (define_insn "*call_indirect_aix<mode>"
10715   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10716          (match_operand 1))
10717    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10718    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10719    (clobber (reg:P LR_REGNO))]
10720   "DEFAULT_ABI == ABI_AIX"
10722   return rs6000_indirect_call_template (operands, 0);
10724   [(set_attr "type" "jmpreg")
10725    (set (attr "length")
10726         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10727                            (match_test "which_alternative != 1"))
10728                       (const_string "16")
10729                       (const_string "12")))])
10731 (define_insn "*call_value_indirect_aix<mode>"
10732   [(set (match_operand 0 "" "")
10733         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10734               (match_operand:P 2 "unspec_tls" "")))
10735    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10736    (set (reg:P TOC_REGNUM)
10737         (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10738                   UNSPEC_TOCSLOT))
10739    (clobber (reg:P LR_REGNO))]
10740   "DEFAULT_ABI == ABI_AIX"
10742   return rs6000_indirect_call_template (operands, 1);
10744   [(set_attr "type" "jmpreg")
10745    (set (attr "length")
10746         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10747                            (match_test "which_alternative != 1"))
10748             (const_string "16")
10749             (const_string "12")))])
10751 ;; Call to indirect functions with the ELFv2 ABI.
10752 ;; Operand0 is the addresss of the function to call
10753 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10755 (define_insn "*call_indirect_elfv2<mode>"
10756   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10757          (match_operand 1))
10758    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10759    (clobber (reg:P LR_REGNO))]
10760   "DEFAULT_ABI == ABI_ELFv2"
10762   return rs6000_indirect_call_template (operands, 0);
10764   [(set_attr "type" "jmpreg")
10765    (set (attr "length")
10766         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10767                            (match_test "which_alternative != 1"))
10768                       (const_string "12")
10769                       (const_string "8")))])
10771 (define_insn "*call_indirect_pcrel<mode>"
10772   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10773          (match_operand 1))
10774    (clobber (reg:P LR_REGNO))]
10775   "rs6000_pcrel_p (cfun)"
10777   return rs6000_indirect_call_template (operands, 0);
10779   [(set_attr "type" "jmpreg")
10780    (set (attr "length")
10781         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10782                            (match_test "which_alternative != 1"))
10783                       (const_string "8")
10784                       (const_string "4")))])
10786 (define_insn "*call_value_indirect_elfv2<mode>"
10787   [(set (match_operand 0 "" "")
10788         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10789               (match_operand:P 2 "unspec_tls" "")))
10790    (set (reg:P TOC_REGNUM)
10791         (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10792                   UNSPEC_TOCSLOT))
10793    (clobber (reg:P LR_REGNO))]
10794   "DEFAULT_ABI == ABI_ELFv2"
10796   return rs6000_indirect_call_template (operands, 1);
10798   [(set_attr "type" "jmpreg")
10799    (set (attr "length")
10800         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10801                            (match_test "which_alternative != 1"))
10802             (const_string "12")
10803             (const_string "8")))])
10805 (define_insn "*call_value_indirect_pcrel<mode>"
10806   [(set (match_operand 0 "" "")
10807         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10808               (match_operand:P 2 "unspec_tls" "")))
10809    (clobber (reg:P LR_REGNO))]
10810   "rs6000_pcrel_p (cfun)"
10812   return rs6000_indirect_call_template (operands, 1);
10814   [(set_attr "type" "jmpreg")
10815    (set (attr "length")
10816         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10817                            (match_test "which_alternative != 1"))
10818             (const_string "8")
10819             (const_string "4")))])
10821 ;; Call subroutine returning any type.
10822 (define_expand "untyped_call"
10823   [(parallel [(call (match_operand 0 "")
10824                     (const_int 0))
10825               (match_operand 1 "")
10826               (match_operand 2 "")])]
10827   ""
10829   int i;
10831   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10833   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10834     {
10835       rtx set = XVECEXP (operands[2], 0, i);
10836       emit_move_insn (SET_DEST (set), SET_SRC (set));
10837     }
10839   /* The optimizer does not know that the call sets the function value
10840      registers we stored in the result block.  We avoid problems by
10841      claiming that all hard registers are used and clobbered at this
10842      point.  */
10843   emit_insn (gen_blockage ());
10845   DONE;
10848 ;; sibling call patterns
10849 (define_expand "sibcall"
10850   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10851                     (match_operand 1 ""))
10852               (use (match_operand 2 ""))
10853               (simple_return)])]
10854   ""
10856 #if TARGET_MACHO
10857   if (MACHOPIC_INDIRECT)
10858     operands[0] = machopic_indirect_call_target (operands[0]);
10859 #endif
10861   gcc_assert (MEM_P (operands[0]));
10862   gcc_assert (CONST_INT_P (operands[1]));
10864   operands[0] = XEXP (operands[0], 0);
10866   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10867     rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10868   else if (DEFAULT_ABI == ABI_V4)
10869     rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10870   else if (DEFAULT_ABI == ABI_DARWIN)
10871     rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10872   else
10873     gcc_unreachable ();
10875   DONE;
10878 (define_expand "sibcall_value"
10879   [(parallel [(set (match_operand 0 "register_operand")
10880                 (call (mem:SI (match_operand 1 "address_operand"))
10881                       (match_operand 2 "")))
10882               (use (match_operand 3 ""))
10883               (simple_return)])]
10884   ""
10886 #if TARGET_MACHO
10887   if (MACHOPIC_INDIRECT)
10888     operands[1] = machopic_indirect_call_target (operands[1]);
10889 #endif
10891   gcc_assert (MEM_P (operands[1]));
10892   gcc_assert (CONST_INT_P (operands[2]));
10894   operands[1] = XEXP (operands[1], 0);
10896   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10897     rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10898   else if (DEFAULT_ABI == ABI_V4)
10899     rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10900   else if (DEFAULT_ABI == ABI_DARWIN)
10901     rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10902   else
10903     gcc_unreachable ();
10905   DONE;
10908 (define_insn "*sibcall_local32"
10909   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10910          (match_operand 1))
10911    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10912    (simple_return)]
10913   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10915   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10916     output_asm_insn ("crxor 6,6,6", operands);
10918   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10919     output_asm_insn ("creqv 6,6,6", operands);
10921   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10923   [(set_attr "type" "branch")
10924    (set_attr "length" "4,8")])
10926 (define_insn "*sibcall_local64"
10927   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10928          (match_operand 1))
10929    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10930    (simple_return)]
10931   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10933   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10934     output_asm_insn ("crxor 6,6,6", operands);
10936   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10937     output_asm_insn ("creqv 6,6,6", operands);
10939   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10941   [(set_attr "type" "branch")
10942    (set_attr "length" "4,8")])
10944 (define_insn "*sibcall_value_local32"
10945   [(set (match_operand 0 "" "")
10946         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10947               (match_operand 2)))
10948    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10949    (simple_return)]
10950   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10952   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10953     output_asm_insn ("crxor 6,6,6", operands);
10955   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10956     output_asm_insn ("creqv 6,6,6", operands);
10958   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10960   [(set_attr "type" "branch")
10961    (set_attr "length" "4,8")])
10963 (define_insn "*sibcall_value_local64"
10964   [(set (match_operand 0 "" "")
10965         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10966               (match_operand 2)))
10967    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10968    (simple_return)]
10969   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10971   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10972     output_asm_insn ("crxor 6,6,6", operands);
10974   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10975     output_asm_insn ("creqv 6,6,6", operands);
10977   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10979   [(set_attr "type" "branch")
10980    (set_attr "length" "4,8")])
10982 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10983   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10984          (match_operand 1))
10985    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10986    (simple_return)]
10987   "DEFAULT_ABI == ABI_V4
10988    || DEFAULT_ABI == ABI_DARWIN"
10990   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10991     output_asm_insn ("crxor 6,6,6", operands);
10993   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10994     output_asm_insn ("creqv 6,6,6", operands);
10996   return rs6000_indirect_sibcall_template (operands, 0);
10998   [(set_attr "type" "jmpreg")
10999    (set (attr "length")
11000         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11001                          (match_test "which_alternative != 1"))
11002                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11003                   (const_string "12")
11004                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11005                          (match_test "which_alternative != 1"))
11006                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11007                   (const_string "8")]
11008               (const_string "4")))])
11010 (define_insn "*sibcall_nonlocal_sysv<mode>"
11011   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11012          (match_operand 1))
11013    (use (match_operand 2 "immediate_operand" "O,n"))
11014    (simple_return)]
11015   "(DEFAULT_ABI == ABI_DARWIN
11016     || DEFAULT_ABI == ABI_V4)
11017    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11019   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11020     output_asm_insn ("crxor 6,6,6", operands);
11022   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11023     output_asm_insn ("creqv 6,6,6", operands);
11025   return rs6000_sibcall_template (operands, 0);
11027   [(set_attr "type" "branch")
11028    (set_attr "length" "4,8")])
11030 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11031   [(set (match_operand 0 "" "")
11032         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11033               (match_operand 2)))
11034    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11035    (simple_return)]
11036   "DEFAULT_ABI == ABI_V4
11037    || DEFAULT_ABI == ABI_DARWIN"
11039   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11040     output_asm_insn ("crxor 6,6,6", operands);
11042   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11043     output_asm_insn ("creqv 6,6,6", operands);
11045   return rs6000_indirect_sibcall_template (operands, 1);
11047   [(set_attr "type" "jmpreg")
11048    (set (attr "length")
11049         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11050                          (match_test "which_alternative != 1"))
11051                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11052                   (const_string "12")
11053                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11054                          (match_test "which_alternative != 1"))
11055                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11056                   (const_string "8")]
11057               (const_string "4")))])
11059 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11060   [(set (match_operand 0 "" "")
11061         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11062               (match_operand 2)))
11063    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11064    (simple_return)]
11065   "(DEFAULT_ABI == ABI_DARWIN
11066     || DEFAULT_ABI == ABI_V4)
11067    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11069   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11070     output_asm_insn ("crxor 6,6,6", operands);
11072   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11073     output_asm_insn ("creqv 6,6,6", operands);
11075   return rs6000_sibcall_template (operands, 1);
11077   [(set_attr "type" "branch")
11078    (set_attr "length" "4,8")])
11080 ;; AIX ABI sibling call patterns.
11082 (define_insn "*sibcall_aix<mode>"
11083   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11084          (match_operand 1))
11085    (simple_return)]
11086   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11088   if (which_alternative == 0)
11089     return rs6000_sibcall_template (operands, 0);
11090   else
11091     return "b%T0";
11093   [(set_attr "type" "branch")])
11095 (define_insn "*sibcall_value_aix<mode>"
11096   [(set (match_operand 0 "" "")
11097         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11098               (match_operand 2)))
11099    (simple_return)]
11100   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11102   if (which_alternative == 0)
11103     return rs6000_sibcall_template (operands, 1);
11104   else
11105     return "b%T1";
11107   [(set_attr "type" "branch")])
11109 (define_expand "sibcall_epilogue"
11110   [(use (const_int 0))]
11111   ""
11113   if (!TARGET_SCHED_PROLOG)
11114     emit_insn (gen_blockage ());
11115   rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11116   DONE;
11119 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11120 ;; all of memory.  This blocks insns from being moved across this point.
11122 (define_insn "blockage"
11123   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11124   ""
11125   ""
11126   [(set_attr "length" "0")])
11128 (define_expand "probe_stack_address"
11129   [(use (match_operand 0 "address_operand"))]
11130   ""
11132   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11133   MEM_VOLATILE_P (operands[0]) = 1;
11135   if (TARGET_64BIT)
11136     emit_insn (gen_probe_stack_di (operands[0]));
11137   else
11138     emit_insn (gen_probe_stack_si (operands[0]));
11139   DONE;
11142 (define_insn "probe_stack_<mode>"
11143   [(set (match_operand:P 0 "memory_operand" "=m")
11144         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11145   ""
11147   operands[1] = gen_rtx_REG (Pmode, 0);
11148   return "st<wd>%U0%X0 %1,%0";
11150   [(set_attr "type" "store")
11151    (set (attr "update")
11152         (if_then_else (match_operand 0 "update_address_mem")
11153                       (const_string "yes")
11154                       (const_string "no")))
11155    (set (attr "indexed")
11156         (if_then_else (match_operand 0 "indexed_address_mem")
11157                       (const_string "yes")
11158                       (const_string "no")))])
11160 (define_insn "probe_stack_range<P:mode>"
11161   [(set (match_operand:P 0 "register_operand" "=&r")
11162         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11163                             (match_operand:P 2 "register_operand" "r")
11164                             (match_operand:P 3 "register_operand" "r")]
11165                            UNSPECV_PROBE_STACK_RANGE))]
11166   ""
11167   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11168   [(set_attr "type" "three")])
11170 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11171 ;; signed & unsigned, and one type of branch.
11173 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11174 ;; insns, and branches.
11176 (define_expand "cbranch<mode>4"
11177   [(use (match_operator 0 "comparison_operator"
11178          [(match_operand:GPR 1 "gpc_reg_operand")
11179           (match_operand:GPR 2 "reg_or_short_operand")]))
11180    (use (match_operand 3))]
11181   ""
11183   /* Take care of the possibility that operands[2] might be negative but
11184      this might be a logical operation.  That insn doesn't exist.  */
11185   if (CONST_INT_P (operands[2])
11186       && INTVAL (operands[2]) < 0)
11187     {
11188       operands[2] = force_reg (<MODE>mode, operands[2]);
11189       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11190                                     GET_MODE (operands[0]),
11191                                     operands[1], operands[2]);
11192    }
11194   rs6000_emit_cbranch (<MODE>mode, operands);
11195   DONE;
11198 (define_expand "cbranch<mode>4"
11199   [(use (match_operator 0 "comparison_operator"
11200          [(match_operand:FP 1 "gpc_reg_operand")
11201           (match_operand:FP 2 "gpc_reg_operand")]))
11202    (use (match_operand 3))]
11203   ""
11205   rs6000_emit_cbranch (<MODE>mode, operands);
11206   DONE;
11209 (define_expand "cstore<mode>4_signed"
11210   [(use (match_operator 1 "signed_comparison_operator"
11211          [(match_operand:P 2 "gpc_reg_operand")
11212           (match_operand:P 3 "gpc_reg_operand")]))
11213    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11214   ""
11216   enum rtx_code cond_code = GET_CODE (operands[1]);
11218   rtx op0 = operands[0];
11219   rtx op1 = operands[2];
11220   rtx op2 = operands[3];
11222   if (cond_code == GE || cond_code == LT)
11223     {
11224       cond_code = swap_condition (cond_code);
11225       std::swap (op1, op2);
11226     }
11228   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11229   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11230   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11232   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11233   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11234   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11236   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11238   if (cond_code == LE)
11239     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11240   else
11241     {
11242       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11243       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11244       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11245     }
11247   DONE;
11250 (define_expand "cstore<mode>4_unsigned"
11251   [(use (match_operator 1 "unsigned_comparison_operator"
11252          [(match_operand:P 2 "gpc_reg_operand")
11253           (match_operand:P 3 "reg_or_short_operand")]))
11254    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11255   ""
11257   enum rtx_code cond_code = GET_CODE (operands[1]);
11259   rtx op0 = operands[0];
11260   rtx op1 = operands[2];
11261   rtx op2 = operands[3];
11263   if (cond_code == GEU || cond_code == LTU)
11264     {
11265       cond_code = swap_condition (cond_code);
11266       std::swap (op1, op2);
11267     }
11269   if (!gpc_reg_operand (op1, <MODE>mode))
11270     op1 = force_reg (<MODE>mode, op1);
11271   if (!reg_or_short_operand (op2, <MODE>mode))
11272     op2 = force_reg (<MODE>mode, op2);
11274   rtx tmp = gen_reg_rtx (<MODE>mode);
11275   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11277   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11278   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11280   if (cond_code == LEU)
11281     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11282   else
11283     emit_insn (gen_neg<mode>2 (op0, tmp2));
11285   DONE;
11288 (define_expand "cstore_si_as_di"
11289   [(use (match_operator 1 "unsigned_comparison_operator"
11290          [(match_operand:SI 2 "gpc_reg_operand")
11291           (match_operand:SI 3 "reg_or_short_operand")]))
11292    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11293   ""
11295   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11296   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11298   operands[2] = force_reg (SImode, operands[2]);
11299   operands[3] = force_reg (SImode, operands[3]);
11300   rtx op1 = gen_reg_rtx (DImode);
11301   rtx op2 = gen_reg_rtx (DImode);
11302   convert_move (op1, operands[2], uns_flag);
11303   convert_move (op2, operands[3], uns_flag);
11305   if (cond_code == GT || cond_code == LE)
11306     {
11307       cond_code = swap_condition (cond_code);
11308       std::swap (op1, op2);
11309     }
11311   rtx tmp = gen_reg_rtx (DImode);
11312   rtx tmp2 = gen_reg_rtx (DImode);
11313   emit_insn (gen_subdi3 (tmp, op1, op2));
11314   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11316   rtx tmp3;
11317   switch (cond_code)
11318     {
11319     default:
11320       gcc_unreachable ();
11321     case LT:
11322       tmp3 = tmp2;
11323       break;
11324     case GE:
11325       tmp3 = gen_reg_rtx (DImode);
11326       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11327       break;
11328     }
11330   convert_move (operands[0], tmp3, 1);
11332   DONE;
11335 (define_expand "cstore<mode>4_signed_imm"
11336   [(use (match_operator 1 "signed_comparison_operator"
11337          [(match_operand:GPR 2 "gpc_reg_operand")
11338           (match_operand:GPR 3 "immediate_operand")]))
11339    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11340   ""
11342   bool invert = false;
11344   enum rtx_code cond_code = GET_CODE (operands[1]);
11346   rtx op0 = operands[0];
11347   rtx op1 = operands[2];
11348   HOST_WIDE_INT val = INTVAL (operands[3]);
11350   if (cond_code == GE || cond_code == GT)
11351     {
11352       cond_code = reverse_condition (cond_code);
11353       invert = true;
11354     }
11356   if (cond_code == LE)
11357     val++;
11359   rtx tmp = gen_reg_rtx (<MODE>mode);
11360   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11361   rtx x = gen_reg_rtx (<MODE>mode);
11362   if (val < 0)
11363     emit_insn (gen_and<mode>3 (x, op1, tmp));
11364   else
11365     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11367   if (invert)
11368     {
11369       rtx tmp = gen_reg_rtx (<MODE>mode);
11370       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11371       x = tmp;
11372     }
11374   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11375   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11377   DONE;
11380 (define_expand "cstore<mode>4_unsigned_imm"
11381   [(use (match_operator 1 "unsigned_comparison_operator"
11382          [(match_operand:GPR 2 "gpc_reg_operand")
11383           (match_operand:GPR 3 "immediate_operand")]))
11384    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11385   ""
11387   bool invert = false;
11389   enum rtx_code cond_code = GET_CODE (operands[1]);
11391   rtx op0 = operands[0];
11392   rtx op1 = operands[2];
11393   HOST_WIDE_INT val = INTVAL (operands[3]);
11395   if (cond_code == GEU || cond_code == GTU)
11396     {
11397       cond_code = reverse_condition (cond_code);
11398       invert = true;
11399     }
11401   if (cond_code == LEU)
11402     val++;
11404   rtx tmp = gen_reg_rtx (<MODE>mode);
11405   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11406   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11407   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11408   rtx x = gen_reg_rtx (<MODE>mode);
11409   if (val < 0)
11410     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11411   else
11412     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11414   if (invert)
11415     {
11416       rtx tmp = gen_reg_rtx (<MODE>mode);
11417       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11418       x = tmp;
11419     }
11421   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11422   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11424   DONE;
11427 (define_expand "cstore<mode>4"
11428   [(use (match_operator 1 "comparison_operator"
11429          [(match_operand:GPR 2 "gpc_reg_operand")
11430           (match_operand:GPR 3 "reg_or_short_operand")]))
11431    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11432   ""
11434   /* Expanding EQ and NE directly to some machine instructions does not help
11435      but does hurt combine.  So don't.  */
11436   if (GET_CODE (operands[1]) == EQ)
11437     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11438   else if (<MODE>mode == Pmode
11439            && GET_CODE (operands[1]) == NE)
11440     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11441   else if (GET_CODE (operands[1]) == NE)
11442     {
11443       rtx tmp = gen_reg_rtx (<MODE>mode);
11444       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11445       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11446     }
11448   /* If ISEL is fast, expand to it.  */
11449   else if (TARGET_ISEL)
11450     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11452   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11453      etc. combinations magically work out just right.  */
11454   else if (<MODE>mode == Pmode
11455            && unsigned_comparison_operator (operands[1], VOIDmode))
11456     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11457                                            operands[2], operands[3]));
11459   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11460   else if (<MODE>mode == SImode && Pmode == DImode)
11461     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11462                                     operands[2], operands[3]));
11464   /* For signed comparisons against a constant, we can do some simple
11465      bit-twiddling.  */
11466   else if (signed_comparison_operator (operands[1], VOIDmode)
11467            && CONST_INT_P (operands[3]))
11468     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11469                                              operands[2], operands[3]));
11471   /* And similarly for unsigned comparisons.  */
11472   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11473            && CONST_INT_P (operands[3]))
11474     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11475                                                operands[2], operands[3]));
11477   /* We also do not want to use mfcr for signed comparisons.  */
11478   else if (<MODE>mode == Pmode
11479            && signed_comparison_operator (operands[1], VOIDmode))
11480     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11481                                          operands[2], operands[3]));
11483   /* Everything else, use the mfcr brute force.  */
11484   else
11485     rs6000_emit_sCOND (<MODE>mode, operands);
11487   DONE;
11490 (define_expand "cstore<mode>4"
11491   [(use (match_operator 1 "comparison_operator"
11492          [(match_operand:FP 2 "gpc_reg_operand")
11493           (match_operand:FP 3 "gpc_reg_operand")]))
11494    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11495   ""
11497   rs6000_emit_sCOND (<MODE>mode, operands);
11498   DONE;
11502 (define_expand "stack_protect_set"
11503   [(match_operand 0 "memory_operand")
11504    (match_operand 1 "memory_operand")]
11505   ""
11507   if (rs6000_stack_protector_guard == SSP_TLS)
11508     {
11509       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11510       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11511       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11512       operands[1] = gen_rtx_MEM (Pmode, addr);
11513     }
11515   if (TARGET_64BIT)
11516     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11517   else
11518     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11520   DONE;
11523 (define_insn "stack_protect_setsi"
11524   [(set (match_operand:SI 0 "memory_operand" "=m")
11525         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11526    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11527   "TARGET_32BIT"
11528   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11529   [(set_attr "type" "three")
11530    (set_attr "length" "12")])
11532 ;; We can't use the prefixed attribute here because there are two memory
11533 ;; instructions.  We can't split the insn due to the fact that this operation
11534 ;; needs to be done in one piece.
11535 (define_insn "stack_protect_setdi"
11536   [(set (match_operand:DI 0 "memory_operand" "=Y")
11537         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11538    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11539   "TARGET_64BIT"
11541   if (prefixed_memory (operands[1], DImode))
11542     output_asm_insn ("pld %2,%1", operands);
11543   else
11544     output_asm_insn ("ld%U1%X1 %2,%1", operands);
11546   if (prefixed_memory (operands[0], DImode))
11547     output_asm_insn ("pstd %2,%0", operands);
11548   else
11549     output_asm_insn ("std%U0%X0 %2,%0", operands);
11551   return "li %2,0";
11553   [(set_attr "type" "three")
11555   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11556   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in 4 bytes for
11557   ;; the LI 0 at the end.
11558    (set_attr "prefixed" "no")
11559    (set_attr "num_insns" "3")
11560    (set (attr "length")
11561         (cond [(and (match_operand 0 "prefixed_memory")
11562                     (match_operand 1 "prefixed_memory"))
11563                (const_int 24)
11565                (ior (match_operand 0 "prefixed_memory")
11566                     (match_operand 1 "prefixed_memory"))
11567                (const_int 20)]
11569               (const_int 12)))])
11571 (define_expand "stack_protect_test"
11572   [(match_operand 0 "memory_operand")
11573    (match_operand 1 "memory_operand")
11574    (match_operand 2 "")]
11575   ""
11577   rtx guard = operands[1];
11579   if (rs6000_stack_protector_guard == SSP_TLS)
11580     {
11581       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11582       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11583       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11584       guard = gen_rtx_MEM (Pmode, addr);
11585     }
11587   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11588   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11589   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11590   emit_jump_insn (jump);
11592   DONE;
11595 (define_insn "stack_protect_testsi"
11596   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11597         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11598                       (match_operand:SI 2 "memory_operand" "m,m")]
11599                      UNSPEC_SP_TEST))
11600    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11601    (clobber (match_scratch:SI 3 "=&r,&r"))]
11602   "TARGET_32BIT"
11603   "@
11604    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11605    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11606   [(set_attr "length" "16,20")])
11608 ;; We can't use the prefixed attribute here because there are two memory
11609 ;; instructions.  We can't split the insn due to the fact that this operation
11610 ;; needs to be done in one piece.
11611 (define_insn "stack_protect_testdi"
11612   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11613         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11614                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11615                      UNSPEC_SP_TEST))
11616    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11617    (clobber (match_scratch:DI 3 "=&r,&r"))]
11618   "TARGET_64BIT"
11620   if (prefixed_memory (operands[1], DImode))
11621     output_asm_insn ("pld %3,%1", operands);
11622   else
11623     output_asm_insn ("ld%U1%X1 %3,%1", operands);
11625   if (prefixed_memory (operands[2], DImode))
11626     output_asm_insn ("pld %4,%2", operands);
11627   else
11628     output_asm_insn ("ld%U2%X2 %4,%2", operands);
11630   if (which_alternative == 0)
11631     output_asm_insn ("xor. %3,%3,%4", operands);
11632   else
11633     output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11635   return "li %4,0";
11637   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11638   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in either 4 or
11639   ;; 8 bytes to do the test.
11640   [(set_attr "prefixed" "no")
11641    (set_attr "num_insns" "4,5")
11642    (set (attr "length")
11643         (cond [(and (match_operand 1 "prefixed_memory")
11644                     (match_operand 2 "prefixed_memory"))
11645                (if_then_else (eq_attr "alternative" "0")
11646                              (const_int 28)
11647                              (const_int 32))
11649                (ior (match_operand 1 "prefixed_memory")
11650                     (match_operand 2 "prefixed_memory"))
11651                (if_then_else (eq_attr "alternative" "0")
11652                              (const_int 20)
11653                              (const_int 24))]
11655               (if_then_else (eq_attr "alternative" "0")
11656                             (const_int 16)
11657                             (const_int 20))))])
11660 ;; Here are the actual compare insns.
11661 (define_insn "*cmp<mode>_signed"
11662   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11663         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11664                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11665   ""
11666   "cmp<wd>%I2 %0,%1,%2"
11667   [(set_attr "type" "cmp")])
11669 (define_insn "*cmp<mode>_unsigned"
11670   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11671         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11672                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11673   ""
11674   "cmpl<wd>%I2 %0,%1,%2"
11675   [(set_attr "type" "cmp")])
11677 ;; If we are comparing a register for equality with a large constant,
11678 ;; we can do this with an XOR followed by a compare.  But this is profitable
11679 ;; only if the large constant is only used for the comparison (and in this
11680 ;; case we already have a register to reuse as scratch).
11682 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11683 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11685 (define_peephole2
11686   [(set (match_operand:SI 0 "register_operand")
11687         (match_operand:SI 1 "logical_const_operand"))
11688    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11689                        [(match_dup 0)
11690                         (match_operand:SI 2 "logical_const_operand")]))
11691    (set (match_operand:CC 4 "cc_reg_operand")
11692         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11693                     (match_dup 0)))
11694    (set (pc)
11695         (if_then_else (match_operator 6 "equality_operator"
11696                        [(match_dup 4) (const_int 0)])
11697                       (match_operand 7 "")
11698                       (match_operand 8 "")))]
11699   "peep2_reg_dead_p (3, operands[0])
11700    && peep2_reg_dead_p (4, operands[4])
11701    && REGNO (operands[0]) != REGNO (operands[5])"
11702  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11703   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11704   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11707   /* Get the constant we are comparing against, and see what it looks like
11708      when sign-extended from 16 to 32 bits.  Then see what constant we could
11709      XOR with SEXTC to get the sign-extended value.  */
11710   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11711                                               SImode,
11712                                               operands[1], operands[2]);
11713   HOST_WIDE_INT c = INTVAL (cnst);
11714   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11715   HOST_WIDE_INT xorv = c ^ sextc;
11717   operands[9] = GEN_INT (xorv);
11718   operands[10] = GEN_INT (sextc);
11721 ;; Only need to compare second words if first words equal
11722 (define_insn "*cmp<mode>_internal1"
11723   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11724         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11725                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11726   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11727    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11728   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11729   [(set_attr "type" "fpcompare")
11730    (set_attr "length" "12")])
11732 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11733   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11734         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11735                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11736     (clobber (match_scratch:DF 3 "=d"))
11737     (clobber (match_scratch:DF 4 "=d"))
11738     (clobber (match_scratch:DF 5 "=d"))
11739     (clobber (match_scratch:DF 6 "=d"))
11740     (clobber (match_scratch:DF 7 "=d"))
11741     (clobber (match_scratch:DF 8 "=d"))
11742     (clobber (match_scratch:DF 9 "=d"))
11743     (clobber (match_scratch:DF 10 "=d"))
11744     (clobber (match_scratch:GPR 11 "=b"))]
11745   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11746    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11747   "#"
11748   "&& reload_completed"
11749   [(set (match_dup 3) (match_dup 14))
11750    (set (match_dup 4) (match_dup 15))
11751    (set (match_dup 9) (abs:DF (match_dup 5)))
11752    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11753    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11754                            (label_ref (match_dup 12))
11755                            (pc)))
11756    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11757    (set (pc) (label_ref (match_dup 13)))
11758    (match_dup 12)
11759    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11760    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11761    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11762    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11763    (match_dup 13)]
11765   REAL_VALUE_TYPE rv;
11766   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11767   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11769   operands[5] = simplify_gen_subreg (DFmode, operands[1],
11770                                      <IBM128:MODE>mode, hi_word);
11771   operands[6] = simplify_gen_subreg (DFmode, operands[1],
11772                                      <IBM128:MODE>mode, lo_word);
11773   operands[7] = simplify_gen_subreg (DFmode, operands[2],
11774                                      <IBM128:MODE>mode, hi_word);
11775   operands[8] = simplify_gen_subreg (DFmode, operands[2],
11776                                      <IBM128:MODE>mode, lo_word);
11777   operands[12] = gen_label_rtx ();
11778   operands[13] = gen_label_rtx ();
11779   real_inf (&rv);
11780   operands[14] = force_const_mem (DFmode,
11781                                   const_double_from_real_value (rv, DFmode));
11782   operands[15] = force_const_mem (DFmode,
11783                                   const_double_from_real_value (dconst0,
11784                                                                 DFmode));
11785   if (TARGET_TOC)
11786     {
11787       rtx tocref;
11788       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11789       operands[14] = gen_const_mem (DFmode, tocref);
11790       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11791       operands[15] = gen_const_mem (DFmode, tocref);
11792       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11793       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11794     }
11797 ;; Now we have the scc insns.  We can do some combinations because of the
11798 ;; way the machine works.
11800 ;; Note that this is probably faster if we can put an insn between the
11801 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11802 ;; cases the insns below which don't use an intermediate CR field will
11803 ;; be used instead.
11804 (define_insn ""
11805   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11806         (match_operator:GPR 1 "scc_comparison_operator"
11807                             [(match_operand 2 "cc_reg_operand" "y")
11808                              (const_int 0)]))]
11809   ""
11810   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11811   [(set (attr "type")
11812      (cond [(match_test "TARGET_MFCRF")
11813                 (const_string "mfcrf")
11814            ]
11815         (const_string "mfcr")))
11816    (set_attr "length" "8")])
11818 (define_insn_and_split ""
11819   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11820         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11821                                        [(match_operand 2 "cc_reg_operand" "y,y")
11822                                         (const_int 0)])
11823                     (const_int 0)))
11824    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11825         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11826   "TARGET_32BIT"
11827   "@
11828    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11829    #"
11830   "&& reload_completed"
11831   [(set (match_dup 3)
11832         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11833    (set (match_dup 0)
11834         (compare:CC (match_dup 3)
11835                     (const_int 0)))]
11836   ""
11837   [(set_attr "type" "shift")
11838    (set_attr "dot" "yes")
11839    (set_attr "length" "8,16")])
11841 (define_insn ""
11842   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11843         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11844                                       [(match_operand 2 "cc_reg_operand" "y")
11845                                        (const_int 0)])
11846                    (match_operand:SI 3 "const_int_operand" "n")))]
11847   ""
11849   int is_bit = ccr_bit (operands[1], 1);
11850   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11851   int count;
11853   gcc_assert (is_bit != -1);
11854   if (is_bit >= put_bit)
11855     count = is_bit - put_bit;
11856   else
11857     count = 32 - (put_bit - is_bit);
11859   operands[4] = GEN_INT (count);
11860   operands[5] = GEN_INT (put_bit);
11862   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11864   [(set (attr "type")
11865      (cond [(match_test "TARGET_MFCRF")
11866                 (const_string "mfcrf")
11867            ]
11868         (const_string "mfcr")))
11869    (set_attr "length" "8")])
11871 (define_insn ""
11872   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11873         (compare:CC
11874          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11875                                        [(match_operand 2 "cc_reg_operand" "y,y")
11876                                         (const_int 0)])
11877                     (match_operand:SI 3 "const_int_operand" "n,n"))
11878          (const_int 0)))
11879    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11880         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11881                    (match_dup 3)))]
11882   ""
11884   int is_bit = ccr_bit (operands[1], 1);
11885   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11886   int count;
11888   gcc_assert (is_bit != -1);
11889   /* Force split for non-cc0 compare.  */
11890   if (which_alternative == 1)
11891      return "#";
11893   if (is_bit >= put_bit)
11894     count = is_bit - put_bit;
11895   else
11896     count = 32 - (put_bit - is_bit);
11898   operands[5] = GEN_INT (count);
11899   operands[6] = GEN_INT (put_bit);
11901   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11903   [(set_attr "type" "shift")
11904    (set_attr "dot" "yes")
11905    (set_attr "length" "8,16")])
11907 (define_split
11908   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11909         (compare:CC
11910          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11911                                        [(match_operand 2 "cc_reg_operand")
11912                                         (const_int 0)])
11913                     (match_operand:SI 3 "const_int_operand"))
11914          (const_int 0)))
11915    (set (match_operand:SI 4 "gpc_reg_operand")
11916         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11917                    (match_dup 3)))]
11918   "reload_completed"
11919   [(set (match_dup 4)
11920         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11921                    (match_dup 3)))
11922    (set (match_dup 0)
11923         (compare:CC (match_dup 4)
11924                     (const_int 0)))]
11925   "")
11928 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11929 (define_code_attr UNS [(eq "CC")
11930                        (ne "CC")
11931                        (lt "CC") (ltu "CCUNS")
11932                        (gt "CC") (gtu "CCUNS")
11933                        (le "CC") (leu "CCUNS")
11934                        (ge "CC") (geu "CCUNS")])
11935 (define_code_attr UNSu_ [(eq "")
11936                          (ne "")
11937                          (lt "") (ltu "u_")
11938                          (gt "") (gtu "u_")
11939                          (le "") (leu "u_")
11940                          (ge "") (geu "u_")])
11941 (define_code_attr UNSIK [(eq "I")
11942                          (ne "I")
11943                          (lt "I") (ltu "K")
11944                          (gt "I") (gtu "K")
11945                          (le "I") (leu "K")
11946                          (ge "I") (geu "K")])
11948 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11949   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11950         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11951                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11952    (clobber (match_scratch:GPR 3 "=r"))
11953    (clobber (match_scratch:GPR 4 "=r"))
11954    (clobber (match_scratch:<UNS> 5 "=y"))]
11955   "TARGET_ISEL
11956    && !(<CODE> == EQ && operands[2] == const0_rtx)
11957    && !(<CODE> == NE && operands[2] == const0_rtx
11958         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11959   "#"
11960   "&& 1"
11961   [(pc)]
11963   rtx_code code = <CODE>;
11964   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11965     {
11966       HOST_WIDE_INT val = INTVAL (operands[2]);
11967       if (code == LT && val != -0x8000)
11968         {
11969           code = LE;
11970           val--;
11971         }
11972       if (code == GT && val != 0x7fff)
11973         {
11974           code = GE;
11975           val++;
11976         }
11977       if (code == LTU && val != 0)
11978         {
11979           code = LEU;
11980           val--;
11981         }
11982       if (code == GTU && val != 0xffff)
11983         {
11984           code = GEU;
11985           val++;
11986         }
11987       operands[2] = GEN_INT (val);
11988     }
11990   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11991     operands[3] = const0_rtx;
11992   else
11993     {
11994       if (GET_CODE (operands[3]) == SCRATCH)
11995         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11996       emit_move_insn (operands[3], const0_rtx);
11997     }
11999   if (GET_CODE (operands[4]) == SCRATCH)
12000     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12001   emit_move_insn (operands[4], const1_rtx);
12003   if (GET_CODE (operands[5]) == SCRATCH)
12004     operands[5] = gen_reg_rtx (<UNS>mode);
12006   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12007   emit_insn (gen_rtx_SET (operands[5], c1));
12009   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12010   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12011   emit_move_insn (operands[0], x);
12013   DONE;
12015   [(set (attr "cost")
12016         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12017                                    || <CODE> == NE
12018                                    || <CODE> == LE || <CODE> == GE
12019                                    || <CODE> == LEU || <CODE> == GEU")
12020                       (const_string "9")
12021                       (const_string "10")))])
12023 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12024                               (DI "rKJI")])
12026 (define_expand "eq<mode>3"
12027   [(parallel [
12028      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12029           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12030                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12031      (clobber (match_scratch:GPR 3 "=r"))
12032      (clobber (match_scratch:GPR 4 "=r"))])]
12033   ""
12035   if (TARGET_ISEL && operands[2] != const0_rtx)
12036     {
12037       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12038                                            operands[2]));
12039       DONE;
12040     }
12043 (define_insn_and_split "*eq<mode>3"
12044   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12045         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12046                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12047    (clobber (match_scratch:GPR 3 "=r"))
12048    (clobber (match_scratch:GPR 4 "=r"))]
12049   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12050   "#"
12051   "&& 1"
12052   [(set (match_dup 4)
12053         (clz:GPR (match_dup 3)))
12054    (set (match_dup 0)
12055         (lshiftrt:GPR (match_dup 4)
12056                       (match_dup 5)))]
12058   operands[3] = rs6000_emit_eqne (<MODE>mode,
12059                                   operands[1], operands[2], operands[3]);
12061   if (GET_CODE (operands[4]) == SCRATCH)
12062     operands[4] = gen_reg_rtx (<MODE>mode);
12064   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12066   [(set (attr "length")
12067         (if_then_else (match_test "operands[2] == const0_rtx")
12068                       (const_string "8")
12069                       (const_string "12")))])
12071 (define_expand "ne<mode>3"
12072   [(parallel [
12073      (set (match_operand:P 0 "gpc_reg_operand" "=r")
12074           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12075                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12076      (clobber (match_scratch:P 3 "=r"))
12077      (clobber (match_scratch:P 4 "=r"))
12078      (clobber (reg:P CA_REGNO))])]
12079   ""
12081   if (TARGET_ISEL && operands[2] != const0_rtx)
12082     {
12083       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12084                                            operands[2]));
12085       DONE;
12086     }
12089 (define_insn_and_split "*ne<mode>3"
12090   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12091         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12092               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12093    (clobber (match_scratch:P 3 "=r"))
12094    (clobber (match_scratch:P 4 "=r"))
12095    (clobber (reg:P CA_REGNO))]
12096   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12097   "#"
12098   "&& 1"
12099   [(parallel [(set (match_dup 4)
12100                    (plus:P (match_dup 3)
12101                            (const_int -1)))
12102               (set (reg:P CA_REGNO)
12103                    (ne:P (match_dup 3)
12104                          (const_int 0)))])
12105    (parallel [(set (match_dup 0)
12106                    (plus:P (plus:P (not:P (match_dup 4))
12107                                    (reg:P CA_REGNO))
12108                            (match_dup 3)))
12109               (clobber (reg:P CA_REGNO))])]
12111   operands[3] = rs6000_emit_eqne (<MODE>mode,
12112                                   operands[1], operands[2], operands[3]);
12114   if (GET_CODE (operands[4]) == SCRATCH)
12115     operands[4] = gen_reg_rtx (<MODE>mode);
12117   [(set (attr "length")
12118         (if_then_else (match_test "operands[2] == const0_rtx")
12119                       (const_string "8")
12120                       (const_string "12")))])
12122 (define_insn_and_split "*neg_eq_<mode>"
12123   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12124         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12125                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12126    (clobber (match_scratch:P 3 "=r"))
12127    (clobber (match_scratch:P 4 "=r"))
12128    (clobber (reg:P CA_REGNO))]
12129   ""
12130   "#"
12131   ""
12132   [(parallel [(set (match_dup 4)
12133                    (plus:P (match_dup 3)
12134                            (const_int -1)))
12135               (set (reg:P CA_REGNO)
12136                    (ne:P (match_dup 3)
12137                          (const_int 0)))])
12138    (parallel [(set (match_dup 0)
12139                    (plus:P (reg:P CA_REGNO)
12140                            (const_int -1)))
12141               (clobber (reg:P CA_REGNO))])]
12143   operands[3] = rs6000_emit_eqne (<MODE>mode,
12144                                   operands[1], operands[2], operands[3]);
12146   if (GET_CODE (operands[4]) == SCRATCH)
12147     operands[4] = gen_reg_rtx (<MODE>mode);
12149   [(set (attr "length")
12150         (if_then_else (match_test "operands[2] == const0_rtx")
12151                       (const_string "8")
12152                       (const_string "12")))])
12154 (define_insn_and_split "*neg_ne_<mode>"
12155   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12156         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12157                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12158    (clobber (match_scratch:P 3 "=r"))
12159    (clobber (match_scratch:P 4 "=r"))
12160    (clobber (reg:P CA_REGNO))]
12161   ""
12162   "#"
12163   ""
12164   [(parallel [(set (match_dup 4)
12165                    (neg:P (match_dup 3)))
12166               (set (reg:P CA_REGNO)
12167                    (eq:P (match_dup 3)
12168                          (const_int 0)))])
12169    (parallel [(set (match_dup 0)
12170                    (plus:P (reg:P CA_REGNO)
12171                            (const_int -1)))
12172               (clobber (reg:P CA_REGNO))])]
12174   operands[3] = rs6000_emit_eqne (<MODE>mode,
12175                                   operands[1], operands[2], operands[3]);
12177   if (GET_CODE (operands[4]) == SCRATCH)
12178     operands[4] = gen_reg_rtx (<MODE>mode);
12180   [(set (attr "length")
12181         (if_then_else (match_test "operands[2] == const0_rtx")
12182                       (const_string "8")
12183                       (const_string "12")))])
12185 (define_insn_and_split "*plus_eq_<mode>"
12186   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12187         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12188                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12189                 (match_operand:P 3 "gpc_reg_operand" "r")))
12190    (clobber (match_scratch:P 4 "=r"))
12191    (clobber (match_scratch:P 5 "=r"))
12192    (clobber (reg:P CA_REGNO))]
12193   ""
12194   "#"
12195   ""
12196   [(parallel [(set (match_dup 5)
12197                    (neg:P (match_dup 4)))
12198               (set (reg:P CA_REGNO)
12199                    (eq:P (match_dup 4)
12200                          (const_int 0)))])
12201    (parallel [(set (match_dup 0)
12202                    (plus:P (match_dup 3)
12203                            (reg:P CA_REGNO)))
12204               (clobber (reg:P CA_REGNO))])]
12206   operands[4] = rs6000_emit_eqne (<MODE>mode,
12207                                   operands[1], operands[2], operands[4]);
12209   if (GET_CODE (operands[5]) == SCRATCH)
12210     operands[5] = gen_reg_rtx (<MODE>mode);
12212   [(set (attr "length")
12213         (if_then_else (match_test "operands[2] == const0_rtx")
12214                       (const_string "8")
12215                       (const_string "12")))])
12217 (define_insn_and_split "*plus_ne_<mode>"
12218   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12219         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12220                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12221                 (match_operand:P 3 "gpc_reg_operand" "r")))
12222    (clobber (match_scratch:P 4 "=r"))
12223    (clobber (match_scratch:P 5 "=r"))
12224    (clobber (reg:P CA_REGNO))]
12225   ""
12226   "#"
12227   ""
12228   [(parallel [(set (match_dup 5)
12229                    (plus:P (match_dup 4)
12230                            (const_int -1)))
12231               (set (reg:P CA_REGNO)
12232                    (ne:P (match_dup 4)
12233                          (const_int 0)))])
12234    (parallel [(set (match_dup 0)
12235                    (plus:P (match_dup 3)
12236                            (reg:P CA_REGNO)))
12237               (clobber (reg:P CA_REGNO))])]
12239   operands[4] = rs6000_emit_eqne (<MODE>mode,
12240                                   operands[1], operands[2], operands[4]);
12242   if (GET_CODE (operands[5]) == SCRATCH)
12243     operands[5] = gen_reg_rtx (<MODE>mode);
12245   [(set (attr "length")
12246         (if_then_else (match_test "operands[2] == const0_rtx")
12247                       (const_string "8")
12248                       (const_string "12")))])
12250 (define_insn_and_split "*minus_eq_<mode>"
12251   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12252         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12253                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12254                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12255    (clobber (match_scratch:P 4 "=r"))
12256    (clobber (match_scratch:P 5 "=r"))
12257    (clobber (reg:P CA_REGNO))]
12258   ""
12259   "#"
12260   ""
12261   [(parallel [(set (match_dup 5)
12262                    (plus:P (match_dup 4)
12263                            (const_int -1)))
12264               (set (reg:P CA_REGNO)
12265                    (ne:P (match_dup 4)
12266                          (const_int 0)))])
12267    (parallel [(set (match_dup 0)
12268                    (plus:P (plus:P (match_dup 3)
12269                                    (reg:P CA_REGNO))
12270                            (const_int -1)))
12271               (clobber (reg:P CA_REGNO))])]
12273   operands[4] = rs6000_emit_eqne (<MODE>mode,
12274                                   operands[1], operands[2], operands[4]);
12276   if (GET_CODE (operands[5]) == SCRATCH)
12277     operands[5] = gen_reg_rtx (<MODE>mode);
12279   [(set (attr "length")
12280         (if_then_else (match_test "operands[2] == const0_rtx")
12281                       (const_string "8")
12282                       (const_string "12")))])
12284 (define_insn_and_split "*minus_ne_<mode>"
12285   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12286         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12287                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12288                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12289    (clobber (match_scratch:P 4 "=r"))
12290    (clobber (match_scratch:P 5 "=r"))
12291    (clobber (reg:P CA_REGNO))]
12292   ""
12293   "#"
12294   ""
12295   [(parallel [(set (match_dup 5)
12296                    (neg:P (match_dup 4)))
12297               (set (reg:P CA_REGNO)
12298                    (eq:P (match_dup 4)
12299                          (const_int 0)))])
12300    (parallel [(set (match_dup 0)
12301                    (plus:P (plus:P (match_dup 3)
12302                                    (reg:P CA_REGNO))
12303                            (const_int -1)))
12304               (clobber (reg:P CA_REGNO))])]
12306   operands[4] = rs6000_emit_eqne (<MODE>mode,
12307                                   operands[1], operands[2], operands[4]);
12309   if (GET_CODE (operands[5]) == SCRATCH)
12310     operands[5] = gen_reg_rtx (<MODE>mode);
12312   [(set (attr "length")
12313         (if_then_else (match_test "operands[2] == const0_rtx")
12314                       (const_string "8")
12315                       (const_string "12")))])
12317 (define_insn_and_split "*eqsi3_ext<mode>"
12318   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12319         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12320                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12321    (clobber (match_scratch:SI 3 "=r"))
12322    (clobber (match_scratch:SI 4 "=r"))]
12323   ""
12324   "#"
12325   ""
12326   [(set (match_dup 4)
12327         (clz:SI (match_dup 3)))
12328    (set (match_dup 0)
12329         (zero_extend:EXTSI
12330           (lshiftrt:SI (match_dup 4)
12331                        (const_int 5))))]
12333   operands[3] = rs6000_emit_eqne (SImode,
12334                                   operands[1], operands[2], operands[3]);
12336   if (GET_CODE (operands[4]) == SCRATCH)
12337     operands[4] = gen_reg_rtx (SImode);
12339   [(set (attr "length")
12340         (if_then_else (match_test "operands[2] == const0_rtx")
12341                       (const_string "8")
12342                       (const_string "12")))])
12344 (define_insn_and_split "*nesi3_ext<mode>"
12345   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12346         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12347                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12348    (clobber (match_scratch:SI 3 "=r"))
12349    (clobber (match_scratch:SI 4 "=r"))
12350    (clobber (match_scratch:EXTSI 5 "=r"))]
12351   "!TARGET_ISEL"
12352   "#"
12353   "&& 1"
12354   [(set (match_dup 4)
12355         (clz:SI (match_dup 3)))
12356    (set (match_dup 5)
12357         (zero_extend:EXTSI
12358           (lshiftrt:SI (match_dup 4)
12359                        (const_int 5))))
12360    (set (match_dup 0)
12361         (xor:EXTSI (match_dup 5)
12362                    (const_int 1)))]
12364   operands[3] = rs6000_emit_eqne (SImode,
12365                                   operands[1], operands[2], operands[3]);
12367   if (GET_CODE (operands[4]) == SCRATCH)
12368     operands[4] = gen_reg_rtx (SImode);
12369   if (GET_CODE (operands[5]) == SCRATCH)
12370     operands[5] = gen_reg_rtx (<MODE>mode);
12372   [(set (attr "length")
12373         (if_then_else (match_test "operands[2] == const0_rtx")
12374                       (const_string "12")
12375                       (const_string "16")))])
12377 ;; Conditional branches.
12378 ;; These either are a single bc insn, or a bc around a b.
12380 (define_insn "*cbranch"
12381   [(set (pc)
12382         (if_then_else (match_operator 1 "branch_comparison_operator"
12383                                       [(match_operand 2 "cc_reg_operand" "y")
12384                                        (const_int 0)])
12385                       (label_ref (match_operand 0))
12386                       (pc)))]
12387   ""
12389   return output_cbranch (operands[1], "%l0", 0, insn);
12391   [(set_attr "type" "branch")
12392    (set (attr "length")
12393         (if_then_else (and (ge (minus (match_dup 0) (pc))
12394                                (const_int -32768))
12395                            (lt (minus (match_dup 0) (pc))
12396                                (const_int 32764)))
12397                       (const_int 4)
12398                       (const_int 8)))])
12400 ;; Conditional return.
12401 (define_insn "*creturn"
12402   [(set (pc)
12403         (if_then_else (match_operator 0 "branch_comparison_operator"
12404                                       [(match_operand 1 "cc_reg_operand" "y")
12405                                        (const_int 0)])
12406                       (any_return)
12407                       (pc)))]
12408   "<return_pred>"
12410   return output_cbranch (operands[0], NULL, 0, insn);
12412   [(set_attr "type" "jmpreg")])
12414 ;; Logic on condition register values.
12416 ; This pattern matches things like
12417 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12418 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12419 ;                                  (const_int 1)))
12420 ; which are generated by the branch logic.
12421 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12423 (define_insn "cceq_ior_compare"
12424   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12425         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12426                         [(match_operator:SI 2
12427                                       "branch_positive_comparison_operator"
12428                                       [(match_operand 3
12429                                                       "cc_reg_operand" "y,y")
12430                                        (const_int 0)])
12431                          (match_operator:SI 4
12432                                       "branch_positive_comparison_operator"
12433                                       [(match_operand 5
12434                                                       "cc_reg_operand" "0,y")
12435                                        (const_int 0)])])
12436                       (const_int 1)))]
12437   ""
12438   "cr%q1 %E0,%j2,%j4"
12439   [(set_attr "type" "cr_logical")
12440    (set_attr "cr_logical_3op" "no,yes")])
12442 ; Why is the constant -1 here, but 1 in the previous pattern?
12443 ; Because ~1 has all but the low bit set.
12444 (define_insn "cceq_ior_compare_complement"
12445   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12446         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12447                         [(not:SI (match_operator:SI 2
12448                                       "branch_positive_comparison_operator"
12449                                       [(match_operand 3
12450                                                       "cc_reg_operand" "y,y")
12451                                        (const_int 0)]))
12452                          (match_operator:SI 4
12453                                 "branch_positive_comparison_operator"
12454                                 [(match_operand 5
12455                                                 "cc_reg_operand" "0,y")
12456                                  (const_int 0)])])
12457                       (const_int -1)))]
12458   ""
12459   "cr%q1 %E0,%j2,%j4"
12460   [(set_attr "type" "cr_logical")
12461    (set_attr "cr_logical_3op" "no,yes")])
12463 (define_insn "*cceq_rev_compare"
12464   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12465         (compare:CCEQ (match_operator:SI 1
12466                                       "branch_positive_comparison_operator"
12467                                       [(match_operand 2
12468                                                       "cc_reg_operand" "0,y")
12469                                        (const_int 0)])
12470                       (const_int 0)))]
12471   ""
12472   "crnot %E0,%j1"
12473   [(set_attr "type" "cr_logical")
12474    (set_attr "cr_logical_3op" "no,yes")])
12476 ;; If we are comparing the result of two comparisons, this can be done
12477 ;; using creqv or crxor.
12479 (define_insn_and_split ""
12480   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12481         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12482                               [(match_operand 2 "cc_reg_operand" "y")
12483                                (const_int 0)])
12484                       (match_operator 3 "branch_comparison_operator"
12485                               [(match_operand 4 "cc_reg_operand" "y")
12486                                (const_int 0)])))]
12487   ""
12488   "#"
12489   ""
12490   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12491                                     (match_dup 5)))]
12493   int positive_1, positive_2;
12495   positive_1 = branch_positive_comparison_operator (operands[1],
12496                                                     GET_MODE (operands[1]));
12497   positive_2 = branch_positive_comparison_operator (operands[3],
12498                                                     GET_MODE (operands[3]));
12500   if (! positive_1)
12501     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12502                                                             GET_CODE (operands[1])),
12503                                   SImode,
12504                                   operands[2], const0_rtx);
12505   else if (GET_MODE (operands[1]) != SImode)
12506     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12507                                   operands[2], const0_rtx);
12509   if (! positive_2)
12510     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12511                                                             GET_CODE (operands[3])),
12512                                   SImode,
12513                                   operands[4], const0_rtx);
12514   else if (GET_MODE (operands[3]) != SImode)
12515     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12516                                   operands[4], const0_rtx);
12518   if (positive_1 == positive_2)
12519     {
12520       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12521       operands[5] = constm1_rtx;
12522     }
12523   else
12524     {
12525       operands[5] = const1_rtx;
12526     }
12529 ;; Unconditional branch and return.
12531 (define_insn "jump"
12532   [(set (pc)
12533         (label_ref (match_operand 0)))]
12534   ""
12535   "b %l0"
12536   [(set_attr "type" "branch")])
12538 (define_insn "<return_str>return"
12539   [(any_return)]
12540   "<return_pred>"
12541   "blr"
12542   [(set_attr "type" "jmpreg")])
12544 (define_expand "indirect_jump"
12545   [(set (pc) (match_operand 0 "register_operand"))]
12546  ""
12548   if (!rs6000_speculate_indirect_jumps) {
12549     rtx ccreg = gen_reg_rtx (CCmode);
12550     emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12551     DONE;
12552   }
12555 (define_insn "*indirect_jump<mode>"
12556   [(set (pc)
12557         (match_operand:P 0 "register_operand" "c,*l"))]
12558   "rs6000_speculate_indirect_jumps"
12559   "b%T0"
12560   [(set_attr "type" "jmpreg")])
12562 (define_insn "@indirect_jump<mode>_nospec"
12563   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12564    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12565   "!rs6000_speculate_indirect_jumps"
12566   "crset %E1\;beq%T0- %1\;b $"
12567   [(set_attr "type" "jmpreg")
12568    (set_attr "length" "12")])
12570 ;; Table jump for switch statements:
12571 (define_expand "tablejump"
12572   [(use (match_operand 0))
12573    (use (label_ref (match_operand 1)))]
12574   ""
12576   if (rs6000_speculate_indirect_jumps)
12577     {
12578       if (TARGET_32BIT)
12579         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12580       else
12581         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12582     }
12583   else
12584     {
12585       rtx ccreg = gen_reg_rtx (CCmode);
12586       rtx jump;
12587       if (TARGET_32BIT)
12588         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12589       else
12590         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12591       emit_jump_insn (jump);
12592     }
12593   DONE;
12596 (define_expand "tablejumpsi"
12597   [(set (match_dup 3)
12598         (plus:SI (match_operand:SI 0)
12599                  (match_dup 2)))
12600    (parallel [(set (pc)
12601                    (match_dup 3))
12602               (use (label_ref (match_operand 1)))])]
12603   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12605   operands[0] = force_reg (SImode, operands[0]);
12606   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12607   operands[3] = gen_reg_rtx (SImode);
12610 (define_expand "tablejumpsi_nospec"
12611   [(set (match_dup 4)
12612         (plus:SI (match_operand:SI 0)
12613                  (match_dup 3)))
12614    (parallel [(set (pc)
12615                    (match_dup 4))
12616               (use (label_ref (match_operand 1)))
12617               (clobber (match_operand 2))])]
12618   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12620   operands[0] = force_reg (SImode, operands[0]);
12621   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12622   operands[4] = gen_reg_rtx (SImode);
12625 (define_expand "tablejumpdi"
12626   [(set (match_dup 4)
12627         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12628    (set (match_dup 3)
12629         (plus:DI (match_dup 4)
12630                  (match_dup 2)))
12631    (parallel [(set (pc)
12632                    (match_dup 3))
12633               (use (label_ref (match_operand 1)))])]
12634   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12636   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12637   operands[3] = gen_reg_rtx (DImode);
12638   operands[4] = gen_reg_rtx (DImode);
12641 (define_expand "tablejumpdi_nospec"
12642   [(set (match_dup 5)
12643         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12644    (set (match_dup 4)
12645         (plus:DI (match_dup 5)
12646                  (match_dup 3)))
12647    (parallel [(set (pc)
12648                    (match_dup 4))
12649               (use (label_ref (match_operand 1)))
12650               (clobber (match_operand 2))])]
12651   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12653   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12654   operands[4] = gen_reg_rtx (DImode);
12655   operands[5] = gen_reg_rtx (DImode);
12658 (define_insn "*tablejump<mode>_internal1"
12659   [(set (pc)
12660         (match_operand:P 0 "register_operand" "c,*l"))
12661    (use (label_ref (match_operand 1)))]
12662   "rs6000_speculate_indirect_jumps"
12663   "b%T0"
12664   [(set_attr "type" "jmpreg")])
12666 (define_insn "*tablejump<mode>_internal1_nospec"
12667   [(set (pc)
12668         (match_operand:P 0 "register_operand" "c,*l"))
12669    (use (label_ref (match_operand 1)))
12670    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12671   "!rs6000_speculate_indirect_jumps"
12672   "crset %E2\;beq%T0- %2\;b $"
12673   [(set_attr "type" "jmpreg")
12674    (set_attr "length" "12")])
12676 (define_insn "nop"
12677   [(unspec [(const_int 0)] UNSPEC_NOP)]
12678   ""
12679   "nop")
12681 (define_insn "group_ending_nop"
12682   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12683   ""
12685   operands[0] = gen_rtx_REG (Pmode,
12686                              rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12687   return "ori %0,%0,0";
12690 (define_insn "speculation_barrier"
12691   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12692   ""
12694   operands[0] = gen_rtx_REG (Pmode, 31);
12695   return "ori %0,%0,0";
12698 ;; Define the subtract-one-and-jump insns, starting with the template
12699 ;; so loop.c knows what to generate.
12701 (define_expand "doloop_end"
12702   [(use (match_operand 0))      ; loop pseudo
12703    (use (match_operand 1))]     ; label
12704   ""
12706   if (GET_MODE (operands[0]) != Pmode)
12707     FAIL;
12709   emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12710   DONE;
12713 (define_expand "@ctr<mode>"
12714   [(parallel [(set (pc)
12715                    (if_then_else (ne (match_operand:P 0 "register_operand")
12716                                      (const_int 1))
12717                                  (label_ref (match_operand 1))
12718                                  (pc)))
12719               (set (match_dup 0)
12720                    (plus:P (match_dup 0)
12721                             (const_int -1)))
12722               (clobber (match_scratch:CC 2))
12723               (clobber (match_scratch:P 3))])]
12724   ""
12725   "")
12727 ;; We need to be able to do this for any operand, including MEM, or we
12728 ;; will cause reload to blow up since we don't allow output reloads on
12729 ;; JUMP_INSNs.
12730 ;; For the length attribute to be calculated correctly, the
12731 ;; label MUST be operand 0.
12732 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12733 ;; the ctr<mode> insns.
12735 (define_code_iterator eqne [eq ne])
12736 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12737 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12739 (define_insn "<bd>_<mode>"
12740   [(set (pc)
12741         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12742                           (const_int 1))
12743                       (label_ref (match_operand 0))
12744                       (pc)))
12745    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12746         (plus:P (match_dup 1)
12747                 (const_int -1)))
12748    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12749    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12750   ""
12752   if (which_alternative != 0)
12753     return "#";
12754   else if (get_attr_length (insn) == 4)
12755     return "<bd> %l0";
12756   else
12757     return "<bd_neg> $+8\;b %l0";
12759   [(set_attr "type" "branch")
12760    (set_attr_alternative "length"
12761      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12762                              (const_int -32768))
12763                          (lt (minus (match_dup 0) (pc))
12764                              (const_int 32764)))
12765                     (const_int 4)
12766                     (const_int 8))
12767       (const_string "16")
12768       (const_string "20")
12769       (const_string "20")])])
12771 ;; Now the splitter if we could not allocate the CTR register
12772 (define_split
12773   [(set (pc)
12774         (if_then_else (match_operator 2 "comparison_operator"
12775                                       [(match_operand:P 1 "gpc_reg_operand")
12776                                        (const_int 1)])
12777                       (match_operand 5)
12778                       (match_operand 6)))
12779    (set (match_operand:P 0 "nonimmediate_operand")
12780         (plus:P (match_dup 1)
12781                 (const_int -1)))
12782    (clobber (match_scratch:CC 3))
12783    (clobber (match_scratch:P 4))]
12784   "reload_completed"
12785   [(set (pc)
12786         (if_then_else (match_dup 7)
12787                       (match_dup 5)
12788                       (match_dup 6)))]
12790   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12791                                 const0_rtx);
12792   emit_insn (gen_rtx_SET (operands[3],
12793                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12794   if (int_reg_operand (operands[0], <MODE>mode))
12795     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12796   else
12797     {
12798       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12799       emit_move_insn (operands[0], operands[4]);
12800     } 
12801     /* No DONE so branch comes from the pattern.  */
12804 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12805 ;; Note that in the case of long branches we have to decompose this into
12806 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12807 ;; and the CR bit, which means there is no way to conveniently invert the
12808 ;; comparison as is done with plain bdnz/bdz.
12810 (define_insn "<bd>tf_<mode>"
12811   [(set (pc)
12812         (if_then_else
12813           (and
12814              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12815                    (const_int 1))
12816              (match_operator 3 "branch_comparison_operator"
12817                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12818                        (const_int 0)]))
12819           (label_ref (match_operand 0))
12820           (pc)))
12821    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12822         (plus:P (match_dup 1)
12823                 (const_int -1)))
12824    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12825    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12826    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12827   ""
12829   if (which_alternative != 0)
12830     return "#";
12831   else if (get_attr_length (insn) == 4)
12832     {
12833       if (branch_positive_comparison_operator (operands[3],
12834                                                GET_MODE (operands[3])))
12835         return "<bd>t %j3,%l0";
12836       else
12837         return "<bd>f %j3,%l0";
12838     }
12839   else
12840     {
12841       static char seq[96];
12842       char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12843       sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12844       return seq;
12845     }
12847   [(set_attr "type" "branch")
12848    (set_attr_alternative "length"
12849      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12850                              (const_int -32768))
12851                          (lt (minus (match_dup 0) (pc))
12852                              (const_int 32764)))
12853                     (const_int 4)
12854                     (const_int 8))
12855       (const_string "16")
12856       (const_string "20")
12857       (const_string "20")])])
12859 ;; Now the splitter if we could not allocate the CTR register
12860 (define_split
12861   [(set (pc)
12862         (if_then_else
12863           (and
12864              (match_operator 1 "comparison_operator"
12865                              [(match_operand:P 0 "gpc_reg_operand")
12866                               (const_int 1)])
12867              (match_operator 3 "branch_comparison_operator"
12868                       [(match_operand 2 "cc_reg_operand")
12869                        (const_int 0)]))
12870           (match_operand 4)
12871           (match_operand 5)))
12872    (set (match_operand:P 6 "nonimmediate_operand")
12873         (plus:P (match_dup 0)
12874                 (const_int -1)))
12875    (clobber (match_scratch:P 7))
12876    (clobber (match_scratch:CC 8))
12877    (clobber (match_scratch:CCEQ 9))]
12878   "reload_completed"
12879 [(pc)]
12881   rtx ctr = operands[0];
12882   rtx ctrcmp = operands[1];
12883   rtx ccin = operands[2];
12884   rtx cccmp = operands[3];
12885   rtx dst1 = operands[4];
12886   rtx dst2 = operands[5];
12887   rtx ctrout = operands[6];
12888   rtx ctrtmp = operands[7];
12889   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12890   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12891   if (!ispos)
12892     cmpcode = reverse_condition (cmpcode);
12893   /* Generate crand/crandc here.  */
12894   emit_insn (gen_rtx_SET (operands[8],
12895                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12896   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12898   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12899   if (ispos)
12900      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12901                                       operands[8], cccmp, ccin));
12902   else
12903      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12904                                                  operands[8], cccmp, ccin));
12905   if (int_reg_operand (ctrout, <MODE>mode))
12906      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12907   else
12908     {
12909       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12910       emit_move_insn (ctrout, ctrtmp);
12911     }
12912   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12913   emit_jump_insn (gen_rtx_SET (pc_rtx,
12914                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12915                                                      dst1, dst2)));
12916   DONE;
12920 (define_insn "trap"
12921   [(trap_if (const_int 1) (const_int 0))]
12922   ""
12923   "trap"
12924   [(set_attr "type" "trap")])
12926 (define_expand "ctrap<mode>4"
12927   [(trap_if (match_operator 0 "ordered_comparison_operator"
12928                             [(match_operand:GPR 1 "register_operand")
12929                              (match_operand:GPR 2 "reg_or_short_operand")])
12930             (match_operand 3 "zero_constant" ""))]
12931   ""
12932   "")
12934 (define_insn ""
12935   [(trap_if (match_operator 0 "ordered_comparison_operator"
12936                             [(match_operand:GPR 1 "register_operand" "r")
12937                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12938             (const_int 0))]
12939   ""
12940   "t<wd>%V0%I2 %1,%2"
12941   [(set_attr "type" "trap")])
12943 ;; Insns related to generating the function prologue and epilogue.
12945 (define_expand "prologue"
12946   [(use (const_int 0))]
12947   ""
12949   rs6000_emit_prologue ();
12950   if (!TARGET_SCHED_PROLOG)
12951     emit_insn (gen_blockage ());
12952   DONE;
12955 (define_insn "*movesi_from_cr_one"
12956   [(match_parallel 0 "mfcr_operation"
12957                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12958                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12959                                      (match_operand 3 "immediate_operand" "n")]
12960                           UNSPEC_MOVESI_FROM_CR))])]
12961   "TARGET_MFCRF"
12963   int mask = 0;
12964   int i;
12965   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12966   {
12967     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12968     operands[4] = GEN_INT (mask);
12969     output_asm_insn ("mfcr %1,%4", operands);
12970   }
12971   return "";
12973   [(set_attr "type" "mfcrf")])
12975 ;; Don't include the volatile CRs since their values are not used wrt CR save
12976 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12977 ;; prologue past an insn (early exit test) that defines a register used in the
12978 ;; prologue.
12979 (define_insn "prologue_movesi_from_cr"
12980   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12981         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12982                     (reg:CC CR4_REGNO)]
12983                    UNSPEC_MOVESI_FROM_CR))]
12984   ""
12985   "mfcr %0"
12986   [(set_attr "type" "mfcr")])
12988 (define_insn "*crsave"
12989   [(match_parallel 0 "crsave_operation"
12990                    [(set (match_operand:SI 1 "memory_operand" "=m")
12991                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12992   ""
12993   "stw %2,%1"
12994   [(set_attr "type" "store")])
12996 (define_insn "*stmw"
12997   [(match_parallel 0 "stmw_operation"
12998                    [(set (match_operand:SI 1 "memory_operand" "=m")
12999                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13000   "TARGET_MULTIPLE"
13001   "stmw %2,%1"
13002   [(set_attr "type" "store")
13003    (set_attr "update" "yes")
13004    (set_attr "indexed" "yes")])
13006 ; The following comment applies to:
13007 ;     save_gpregs_*
13008 ;     save_fpregs_*
13009 ;     restore_gpregs*
13010 ;     return_and_restore_gpregs*
13011 ;     return_and_restore_fpregs*
13012 ;     return_and_restore_fpregs_aix*
13014 ; The out-of-line save / restore functions expects one input argument.
13015 ; Since those are not standard call_insn's, we must avoid using
13016 ; MATCH_OPERAND for that argument. That way the register rename
13017 ; optimization will not try to rename this register.
13018 ; Each pattern is repeated for each possible register number used in 
13019 ; various ABIs (r11, r1, and for some functions r12)
13021 (define_insn "*save_gpregs_<mode>_r11"
13022   [(match_parallel 0 "any_parallel_operand"
13023                    [(clobber (reg:P LR_REGNO))
13024                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13025                     (use (reg:P 11))
13026                     (set (match_operand:P 2 "memory_operand" "=m")
13027                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13028   ""
13029   "bl %1"
13030   [(set_attr "type" "branch")])
13032 (define_insn "*save_gpregs_<mode>_r12"
13033   [(match_parallel 0 "any_parallel_operand"
13034                    [(clobber (reg:P LR_REGNO))
13035                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13036                     (use (reg:P 12))
13037                     (set (match_operand:P 2 "memory_operand" "=m")
13038                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13039   ""
13040   "bl %1"
13041   [(set_attr "type" "branch")])
13043 (define_insn "*save_gpregs_<mode>_r1"
13044   [(match_parallel 0 "any_parallel_operand"
13045                    [(clobber (reg:P LR_REGNO))
13046                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13047                     (use (reg:P 1))
13048                     (set (match_operand:P 2 "memory_operand" "=m")
13049                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13050   ""
13051   "bl %1"
13052   [(set_attr "type" "branch")])
13054 (define_insn "*save_fpregs_<mode>_r11"
13055   [(match_parallel 0 "any_parallel_operand"
13056                    [(clobber (reg:P LR_REGNO))
13057                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13058                     (use (reg:P 11))
13059                     (set (match_operand:DF 2 "memory_operand" "=m")
13060                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13061   ""
13062   "bl %1"
13063   [(set_attr "type" "branch")])
13065 (define_insn "*save_fpregs_<mode>_r12"
13066   [(match_parallel 0 "any_parallel_operand"
13067                    [(clobber (reg:P LR_REGNO))
13068                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13069                     (use (reg:P 12))
13070                     (set (match_operand:DF 2 "memory_operand" "=m")
13071                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13072   ""
13073   "bl %1"
13074   [(set_attr "type" "branch")])
13076 (define_insn "*save_fpregs_<mode>_r1"
13077   [(match_parallel 0 "any_parallel_operand"
13078                    [(clobber (reg:P LR_REGNO))
13079                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13080                     (use (reg:P 1))
13081                     (set (match_operand:DF 2 "memory_operand" "=m")
13082                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13083   ""
13084   "bl %1"
13085   [(set_attr "type" "branch")])
13087 ; This is to explain that changes to the stack pointer should
13088 ; not be moved over loads from or stores to stack memory.
13089 (define_insn "stack_tie"
13090   [(match_parallel 0 "tie_operand"
13091                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13092   ""
13093   ""
13094   [(set_attr "length" "0")])
13096 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13097 ; stay behind all restores from the stack, it cannot be reordered to before
13098 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13099 (define_insn "stack_restore_tie"
13100   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13101         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13102                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13103    (set (mem:BLK (scratch)) (const_int 0))]
13104   "TARGET_32BIT"
13105   "@
13106    mr %0,%1
13107    add%I2 %0,%1,%2"
13108   [(set_attr "type" "*,add")])
13110 (define_expand "epilogue"
13111   [(use (const_int 0))]
13112   ""
13114   if (!TARGET_SCHED_PROLOG)
13115     emit_insn (gen_blockage ());
13116   rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13117   DONE;
13120 ; On some processors, doing the mtcrf one CC register at a time is
13121 ; faster (like on the 604e).  On others, doing them all at once is
13122 ; faster; for instance, on the 601 and 750.
13124 (define_expand "movsi_to_cr_one"
13125   [(set (match_operand:CC 0 "cc_reg_operand")
13126         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13127                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13128   ""
13129   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13131 (define_insn "*movsi_to_cr"
13132   [(match_parallel 0 "mtcrf_operation"
13133                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13134                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13135                                      (match_operand 3 "immediate_operand" "n")]
13136                                     UNSPEC_MOVESI_TO_CR))])]
13137  ""
13139   int mask = 0;
13140   int i;
13141   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13142     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13143   operands[4] = GEN_INT (mask);
13144   return "mtcrf %4,%2";
13146   [(set_attr "type" "mtcr")])
13148 (define_insn "*mtcrfsi"
13149   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13150         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13151                     (match_operand 2 "immediate_operand" "n")]
13152                    UNSPEC_MOVESI_TO_CR))]
13153   "REG_P (operands[0])
13154    && CR_REGNO_P (REGNO (operands[0]))
13155    && CONST_INT_P (operands[2])
13156    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13157   "mtcrf %R0,%1"
13158   [(set_attr "type" "mtcr")])
13160 ; The load-multiple instructions have similar properties.
13161 ; Note that "load_multiple" is a name known to the machine-independent
13162 ; code that actually corresponds to the PowerPC load-string.
13164 (define_insn "*lmw"
13165   [(match_parallel 0 "lmw_operation"
13166                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13167                          (match_operand:SI 2 "memory_operand" "m"))])]
13168   "TARGET_MULTIPLE"
13169   "lmw %1,%2"
13170   [(set_attr "type" "load")
13171    (set_attr "update" "yes")
13172    (set_attr "indexed" "yes")
13173    (set_attr "cell_micro" "always")])
13175 ; FIXME: "any_parallel_operand" is a bit flexible...
13177 ; The following comment applies to:
13178 ;     save_gpregs_*
13179 ;     save_fpregs_*
13180 ;     restore_gpregs*
13181 ;     return_and_restore_gpregs*
13182 ;     return_and_restore_fpregs*
13183 ;     return_and_restore_fpregs_aix*
13185 ; The out-of-line save / restore functions expects one input argument.
13186 ; Since those are not standard call_insn's, we must avoid using
13187 ; MATCH_OPERAND for that argument. That way the register rename
13188 ; optimization will not try to rename this register.
13189 ; Each pattern is repeated for each possible register number used in 
13190 ; various ABIs (r11, r1, and for some functions r12)
13192 (define_insn "*restore_gpregs_<mode>_r11"
13193  [(match_parallel 0 "any_parallel_operand"
13194                   [(clobber (reg:P LR_REGNO))
13195                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13196                    (use (reg:P 11))
13197                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13198                         (match_operand:P 3 "memory_operand" "m"))])]
13199  ""
13200  "bl %1"
13201  [(set_attr "type" "branch")])
13203 (define_insn "*restore_gpregs_<mode>_r12"
13204  [(match_parallel 0 "any_parallel_operand"
13205                   [(clobber (reg:P LR_REGNO))
13206                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13207                    (use (reg:P 12))
13208                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13209                         (match_operand:P 3 "memory_operand" "m"))])]
13210  ""
13211  "bl %1"
13212  [(set_attr "type" "branch")])
13214 (define_insn "*restore_gpregs_<mode>_r1"
13215  [(match_parallel 0 "any_parallel_operand"
13216                   [(clobber (reg:P LR_REGNO))
13217                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13218                    (use (reg:P 1))
13219                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13220                         (match_operand:P 3 "memory_operand" "m"))])]
13221  ""
13222  "bl %1"
13223  [(set_attr "type" "branch")])
13225 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13226  [(match_parallel 0 "any_parallel_operand"
13227                   [(return)
13228                    (clobber (reg:P LR_REGNO))
13229                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13230                    (use (reg:P 11))
13231                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13232                         (match_operand:P 3 "memory_operand" "m"))])]
13233  ""
13234  "b %1"
13235  [(set_attr "type" "branch")])
13237 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13238  [(match_parallel 0 "any_parallel_operand"
13239                   [(return)
13240                    (clobber (reg:P LR_REGNO))
13241                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13242                    (use (reg:P 12))
13243                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13244                         (match_operand:P 3 "memory_operand" "m"))])]
13245  ""
13246  "b %1"
13247  [(set_attr "type" "branch")])
13249 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13250  [(match_parallel 0 "any_parallel_operand"
13251                   [(return)
13252                    (clobber (reg:P LR_REGNO))
13253                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13254                    (use (reg:P 1))
13255                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13256                         (match_operand:P 3 "memory_operand" "m"))])]
13257  ""
13258  "b %1"
13259  [(set_attr "type" "branch")])
13261 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13262  [(match_parallel 0 "any_parallel_operand"
13263                   [(return)
13264                    (clobber (reg:P LR_REGNO))
13265                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13266                    (use (reg:P 11))
13267                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13268                         (match_operand:DF 3 "memory_operand" "m"))])]
13269  ""
13270  "b %1"
13271  [(set_attr "type" "branch")])
13273 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13274  [(match_parallel 0 "any_parallel_operand"
13275                   [(return)
13276                    (clobber (reg:P LR_REGNO))
13277                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13278                    (use (reg:P 12))
13279                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13280                         (match_operand:DF 3 "memory_operand" "m"))])]
13281  ""
13282  "b %1"
13283  [(set_attr "type" "branch")])
13285 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13286  [(match_parallel 0 "any_parallel_operand"
13287                   [(return)
13288                    (clobber (reg:P LR_REGNO))
13289                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13290                    (use (reg:P 1))
13291                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13292                         (match_operand:DF 3 "memory_operand" "m"))])]
13293  ""
13294  "b %1"
13295  [(set_attr "type" "branch")])
13297 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13298  [(match_parallel 0 "any_parallel_operand"
13299                   [(return)
13300                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13301                    (use (reg:P 11))
13302                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13303                         (match_operand:DF 3 "memory_operand" "m"))])]
13304  ""
13305  "b %1"
13306  [(set_attr "type" "branch")])
13308 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13309  [(match_parallel 0 "any_parallel_operand"
13310                   [(return)
13311                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13312                    (use (reg:P 1))
13313                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13314                         (match_operand:DF 3 "memory_operand" "m"))])]
13315  ""
13316  "b %1"
13317  [(set_attr "type" "branch")])
13319 ; This is used in compiling the unwind routines.
13320 (define_expand "eh_return"
13321   [(use (match_operand 0 "general_operand"))]
13322   ""
13324   emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13325   DONE;
13328 ; We can't expand this before we know where the link register is stored.
13329 (define_insn_and_split "@eh_set_lr_<mode>"
13330   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13331    (clobber (match_scratch:P 1 "=&b"))]
13332   ""
13333   "#"
13334   "reload_completed"
13335   [(const_int 0)]
13337   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13338   DONE;
13341 (define_insn "prefetch"
13342   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13343              (match_operand:SI 1 "const_int_operand" "n")
13344              (match_operand:SI 2 "const_int_operand" "n"))]
13345   ""
13349   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13350      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13351      The AIX assembler does not support the three operand form of dcbt
13352      and dcbtst on Power 7 (-mpwr7).  */
13353   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13355   if (REG_P (operands[0]))
13356     {
13357       if (INTVAL (operands[1]) == 0)
13358         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13359       else
13360         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13361     }
13362   else
13363     {
13364       if (INTVAL (operands[1]) == 0)
13365         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13366       else
13367         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13368     }
13370   [(set_attr "type" "load")])
13372 ;; Handle -fsplit-stack.
13374 (define_expand "split_stack_prologue"
13375   [(const_int 0)]
13376   ""
13378   rs6000_expand_split_stack_prologue ();
13379   DONE;
13382 (define_expand "load_split_stack_limit"
13383   [(set (match_operand 0)
13384         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13385   ""
13387   emit_insn (gen_rtx_SET (operands[0],
13388                           gen_rtx_UNSPEC (Pmode,
13389                                           gen_rtvec (1, const0_rtx),
13390                                           UNSPEC_STACK_CHECK)));
13391   DONE;
13394 (define_insn "load_split_stack_limit_di"
13395   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13396         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13397   "TARGET_64BIT"
13398   "ld %0,-0x7040(13)"
13399   [(set_attr "type" "load")
13400    (set_attr "update" "no")
13401    (set_attr "indexed" "no")])
13403 (define_insn "load_split_stack_limit_si"
13404   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13405         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13406   "!TARGET_64BIT"
13407   "lwz %0,-0x7020(2)"
13408   [(set_attr "type" "load")
13409    (set_attr "update" "no")
13410    (set_attr "indexed" "no")])
13412 ;; A return instruction which the middle-end doesn't see.
13413 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13414 ;; after the call to __morestack.
13415 (define_insn "split_stack_return"
13416   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13417   ""
13418   "blr"
13419   [(set_attr "type" "jmpreg")])
13421 ;; If there are operand 0 bytes available on the stack, jump to
13422 ;; operand 1.
13423 (define_expand "split_stack_space_check"
13424   [(set (match_dup 2)
13425         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13426    (set (match_dup 3)
13427         (minus (reg STACK_POINTER_REGNUM)
13428                (match_operand 0)))
13429    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13430    (set (pc) (if_then_else
13431               (geu (match_dup 4) (const_int 0))
13432               (label_ref (match_operand 1))
13433               (pc)))]
13434   ""
13436   rs6000_split_stack_space_check (operands[0], operands[1]);
13437   DONE;
13440 (define_insn "bpermd_<mode>"
13441   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13442         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13443                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13444   "TARGET_POPCNTD"
13445   "bpermd %0,%1,%2"
13446   [(set_attr "type" "popcnt")])
13449 ;; Builtin fma support.  Handle 
13450 ;; Note that the conditions for expansion are in the FMA_F iterator.
13452 (define_expand "fma<mode>4"
13453   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13454         (fma:FMA_F
13455           (match_operand:FMA_F 1 "gpc_reg_operand")
13456           (match_operand:FMA_F 2 "gpc_reg_operand")
13457           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13458   ""
13459   "")
13461 (define_insn "*fma<mode>4_fpr"
13462   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13463         (fma:SFDF
13464           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13465           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13466           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13467   "TARGET_HARD_FLOAT"
13468   "@
13469    fmadd<s> %0,%1,%2,%3
13470    xsmadda<sd>p %x0,%x1,%x2
13471    xsmaddm<sd>p %x0,%x1,%x3"
13472   [(set_attr "type" "fp")
13473    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13475 ; Altivec only has fma and nfms.
13476 (define_expand "fms<mode>4"
13477   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13478         (fma:FMA_F
13479           (match_operand:FMA_F 1 "gpc_reg_operand")
13480           (match_operand:FMA_F 2 "gpc_reg_operand")
13481           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13482   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13483   "")
13485 (define_insn "*fms<mode>4_fpr"
13486   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13487         (fma:SFDF
13488          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13489          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13490          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13491   "TARGET_HARD_FLOAT"
13492   "@
13493    fmsub<s> %0,%1,%2,%3
13494    xsmsuba<sd>p %x0,%x1,%x2
13495    xsmsubm<sd>p %x0,%x1,%x3"
13496   [(set_attr "type" "fp")
13497    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13499 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13500 (define_expand "fnma<mode>4"
13501   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13502         (neg:FMA_F
13503           (fma:FMA_F
13504             (match_operand:FMA_F 1 "gpc_reg_operand")
13505             (match_operand:FMA_F 2 "gpc_reg_operand")
13506             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13507   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13508   "")
13510 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13511 (define_expand "fnms<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             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13518   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13519   "")
13521 ; Not an official optab name, but used from builtins.
13522 (define_expand "nfma<mode>4"
13523   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13524         (neg:FMA_F
13525           (fma:FMA_F
13526             (match_operand:FMA_F 1 "gpc_reg_operand")
13527             (match_operand:FMA_F 2 "gpc_reg_operand")
13528             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13529   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13530   "")
13532 (define_insn "*nfma<mode>4_fpr"
13533   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13534         (neg:SFDF
13535          (fma:SFDF
13536           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13537           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13538           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13539   "TARGET_HARD_FLOAT"
13540   "@
13541    fnmadd<s> %0,%1,%2,%3
13542    xsnmadda<sd>p %x0,%x1,%x2
13543    xsnmaddm<sd>p %x0,%x1,%x3"
13544   [(set_attr "type" "fp")
13545    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13547 ; Not an official optab name, but used from builtins.
13548 (define_expand "nfms<mode>4"
13549   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13550         (neg:FMA_F
13551           (fma:FMA_F
13552             (match_operand:FMA_F 1 "gpc_reg_operand")
13553             (match_operand:FMA_F 2 "gpc_reg_operand")
13554             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13555   ""
13556   "")
13558 (define_insn "*nfmssf4_fpr"
13559   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13560         (neg:SFDF
13561          (fma:SFDF
13562           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13563           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13564           (neg:SFDF
13565            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13566   "TARGET_HARD_FLOAT"
13567   "@
13568    fnmsub<s> %0,%1,%2,%3
13569    xsnmsuba<sd>p %x0,%x1,%x2
13570    xsnmsubm<sd>p %x0,%x1,%x3"
13571   [(set_attr "type" "fp")
13572    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13574 (define_expand "rs6000_get_timebase"
13575   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13576   ""
13578   if (TARGET_POWERPC64)
13579     emit_insn (gen_rs6000_mftb_di (operands[0]));
13580   else
13581     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13582   DONE;
13585 (define_insn "rs6000_get_timebase_ppc32"
13586   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13587         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13588    (clobber (match_scratch:SI 1 "=r"))
13589    (clobber (match_scratch:CC 2 "=y"))]
13590   "!TARGET_POWERPC64"
13592   if (WORDS_BIG_ENDIAN)
13593     if (TARGET_MFCRF)
13594       {
13595         return "mfspr %0,269\;"
13596                "mfspr %L0,268\;"
13597                "mfspr %1,269\;"
13598                "cmpw %2,%0,%1\;"
13599                "bne- %2,$-16";
13600       }
13601     else
13602       {
13603         return "mftbu %0\;"
13604                "mftb %L0\;"
13605                "mftbu %1\;"
13606                "cmpw %2,%0,%1\;"
13607                "bne- %2,$-16";
13608       }
13609   else
13610     if (TARGET_MFCRF)
13611       {
13612         return "mfspr %L0,269\;"
13613                "mfspr %0,268\;"
13614                "mfspr %1,269\;"
13615                "cmpw %2,%L0,%1\;"
13616                "bne- %2,$-16";
13617       }
13618     else
13619       {
13620         return "mftbu %L0\;"
13621                "mftb %0\;"
13622                "mftbu %1\;"
13623                "cmpw %2,%L0,%1\;"
13624                "bne- %2,$-16";
13625       }
13627   [(set_attr "length" "20")])
13629 (define_insn "rs6000_mftb_<mode>"
13630   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13631         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13632   ""
13634   if (TARGET_MFCRF)
13635     return "mfspr %0,268";
13636   else
13637     return "mftb %0";
13641 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13642 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13643 (define_insn "rs6000_mffsl_hw"
13644   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13645         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13646   "TARGET_HARD_FLOAT"
13647   "mffsl %0")
13649 (define_expand "rs6000_mffsl"
13650   [(set (match_operand:DF 0 "gpc_reg_operand")
13651         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13652   "TARGET_HARD_FLOAT"
13654   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13655      otherwise fall back to the older mffs instruction to emulate the mffsl
13656      instruction.  */
13658   if (!TARGET_P9_MISC)
13659     {
13660        rtx tmp_di = gen_reg_rtx (DImode);
13661        rtx tmp_df = gen_reg_rtx (DFmode);
13663        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13664           instruction using the mffs instruction and masking off the bits
13665           the mmsl instruciton actually reads.  */
13666        emit_insn (gen_rs6000_mffs (tmp_df));
13667        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13668        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13670        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13671        DONE;
13672     }
13674     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13675     DONE;
13678 (define_insn "rs6000_mffs"
13679   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13680         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13681   "TARGET_HARD_FLOAT"
13682   "mffs %0")
13684 (define_insn "rs6000_mtfsf"
13685   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13686                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13687                     UNSPECV_MTFSF)]
13688   "TARGET_HARD_FLOAT"
13689   "mtfsf %0,%1")
13691 (define_insn "rs6000_mtfsf_hi"
13692   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13693                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13694                     UNSPECV_MTFSF_HI)]
13695   "TARGET_HARD_FLOAT"
13696   "mtfsf %0,%1,0,1")
13699 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13700 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13701 ;; register that is being loaded.  The fused ops must be physically adjacent.
13703 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13704 ;; peephole2 then gathers any other fused possibilities that it can find after
13705 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13706 ;; point loads/stores.
13708 ;; Find cases where the addis that feeds into a load instruction is either used
13709 ;; once or is the same as the target register, and replace it with the fusion
13710 ;; insn
13712 (define_peephole2
13713   [(set (match_operand:P 0 "base_reg_operand")
13714         (match_operand:P 1 "fusion_gpr_addis"))
13715    (set (match_operand:INT1 2 "base_reg_operand")
13716         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13717   "TARGET_P8_FUSION
13718    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13719                          operands[3])"
13720   [(const_int 0)]
13722   expand_fusion_gpr_load (operands);
13723   DONE;
13726 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13727 ;; reload)
13729 (define_insn "*fusion_gpr_load_<mode>"
13730   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13731         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13732                      UNSPEC_FUSION_GPR))]
13733   "TARGET_P8_FUSION"
13735   return emit_fusion_gpr_load (operands[0], operands[1]);
13737   [(set_attr "type" "load")
13738    (set_attr "length" "8")])
13741 ;; Optimize cases where we want to do a D-form load (register+offset) on
13742 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13743 ;; has generated:
13744 ;;      LFD 0,32(3)
13745 ;;      XXLOR 32,0,0
13747 ;; and we change this to:
13748 ;;      LI 0,32
13749 ;;      LXSDX 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 "simple_offsettable_mem_operand"))
13755    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_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 3)
13761         (match_dup 5))]
13763   rtx tmp_reg = operands[0];
13764   rtx mem = operands[2];
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);
13778 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13779 ;; Altivec register, and the register allocator has generated:
13780 ;;      XXLOR 0,32,32
13781 ;;      STFD 0,32(3)
13783 ;; and we change this to:
13784 ;;      LI 0,32
13785 ;;      STXSDX 32,3,9
13787 (define_peephole2
13788   [(match_scratch:P 0 "b")
13789    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13790         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13791    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13792         (match_dup 1))]
13793   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13794   [(set (match_dup 0)
13795         (match_dup 4))
13796    (set (match_dup 5)
13797         (match_dup 2))]
13799   rtx tmp_reg = operands[0];
13800   rtx mem = operands[3];
13801   rtx addr = XEXP (mem, 0);
13802   rtx add_op0, add_op1, new_addr;
13804   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13805   add_op0 = XEXP (addr, 0);
13806   add_op1 = XEXP (addr, 1);
13807   gcc_assert (REG_P (add_op0));
13808   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13810   operands[4] = add_op1;
13811   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13813    
13815 ;; Miscellaneous ISA 2.06 (power7) instructions
13816 (define_insn "addg6s"
13817   [(set (match_operand:SI 0 "register_operand" "=r")
13818         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13819                     (match_operand:SI 2 "register_operand" "r")]
13820                    UNSPEC_ADDG6S))]
13821   "TARGET_POPCNTD"
13822   "addg6s %0,%1,%2"
13823   [(set_attr "type" "integer")])
13825 (define_insn "cdtbcd"
13826   [(set (match_operand:SI 0 "register_operand" "=r")
13827         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13828                    UNSPEC_CDTBCD))]
13829   "TARGET_POPCNTD"
13830   "cdtbcd %0,%1"
13831   [(set_attr "type" "integer")])
13833 (define_insn "cbcdtd"
13834   [(set (match_operand:SI 0 "register_operand" "=r")
13835         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13836                    UNSPEC_CBCDTD))]
13837   "TARGET_POPCNTD"
13838   "cbcdtd %0,%1"
13839   [(set_attr "type" "integer")])
13841 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13842                                         UNSPEC_DIVEU])
13844 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13845                              (UNSPEC_DIVEU      "eu")])
13847 (define_insn "div<div_extend>_<mode>"
13848   [(set (match_operand:GPR 0 "register_operand" "=r")
13849         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13850                      (match_operand:GPR 2 "register_operand" "r")]
13851                     UNSPEC_DIV_EXTEND))]
13852   "TARGET_POPCNTD"
13853   "div<wd><div_extend> %0,%1,%2"
13854   [(set_attr "type" "div")
13855    (set_attr "size" "<bits>")])
13858 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13860 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13861 (define_mode_attr FP128_64 [(TF "DF")
13862                             (IF "DF")
13863                             (TD "DI")
13864                             (KF "DI")])
13866 (define_expand "unpack<mode>"
13867   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13868         (unspec:<FP128_64>
13869          [(match_operand:FMOVE128 1 "register_operand")
13870           (match_operand:QI 2 "const_0_to_1_operand")]
13871          UNSPEC_UNPACK_128BIT))]
13872   "FLOAT128_2REG_P (<MODE>mode)"
13873   "")
13875 (define_insn_and_split "unpack<mode>_dm"
13876   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13877         (unspec:<FP128_64>
13878          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13879           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13880          UNSPEC_UNPACK_128BIT))]
13881   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13882   "#"
13883   "&& reload_completed"
13884   [(set (match_dup 0) (match_dup 3))]
13886   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13888   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13889     {
13890       emit_note (NOTE_INSN_DELETED);
13891       DONE;
13892     }
13894   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13896   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13898 (define_insn_and_split "unpack<mode>_nodm"
13899   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13900         (unspec:<FP128_64>
13901          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13902           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13903          UNSPEC_UNPACK_128BIT))]
13904   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13905   "#"
13906   "&& reload_completed"
13907   [(set (match_dup 0) (match_dup 3))]
13909   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13911   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13912     {
13913       emit_note (NOTE_INSN_DELETED);
13914       DONE;
13915     }
13917   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13919   [(set_attr "type" "fp,fpstore")])
13921 (define_insn_and_split "pack<mode>"
13922   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13923         (unspec:FMOVE128
13924          [(match_operand:<FP128_64> 1 "register_operand" "d")
13925           (match_operand:<FP128_64> 2 "register_operand" "d")]
13926          UNSPEC_PACK_128BIT))]
13927   "FLOAT128_2REG_P (<MODE>mode)"
13928   "#"
13929   "&& reload_completed"
13930   [(set (match_dup 3) (match_dup 1))
13931    (set (match_dup 4) (match_dup 2))]
13933   unsigned dest_hi = REGNO (operands[0]);
13934   unsigned dest_lo = dest_hi + 1;
13936   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13937   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13939   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13940   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13942   [(set_attr "type" "fp")
13943    (set_attr "length" "8")])
13945 (define_insn "unpack<mode>"
13946   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13947         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13948                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13949          UNSPEC_UNPACK_128BIT))]
13950   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13952   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13953     return ASM_COMMENT_START " xxpermdi to same register";
13955   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13956   return "xxpermdi %x0,%x1,%x1,%3";
13958   [(set_attr "type" "vecperm")])
13960 (define_insn "pack<mode>"
13961   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13962         (unspec:FMOVE128_VSX
13963          [(match_operand:DI 1 "register_operand" "wa")
13964           (match_operand:DI 2 "register_operand" "wa")]
13965          UNSPEC_PACK_128BIT))]
13966   "TARGET_VSX"
13967   "xxpermdi %x0,%x1,%x2,0"
13968   [(set_attr "type" "vecperm")])
13972 ;; ISA 2.08 IEEE 128-bit floating point support.
13974 (define_insn "add<mode>3"
13975   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13976         (plus:IEEE128
13977          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13978          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13979   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13980   "xsaddqp %0,%1,%2"
13981   [(set_attr "type" "vecfloat")
13982    (set_attr "size" "128")])
13984 (define_insn "sub<mode>3"
13985   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13986         (minus:IEEE128
13987          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13988          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13989   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13990   "xssubqp %0,%1,%2"
13991   [(set_attr "type" "vecfloat")
13992    (set_attr "size" "128")])
13994 (define_insn "mul<mode>3"
13995   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13996         (mult:IEEE128
13997          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13998          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13999   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14000   "xsmulqp %0,%1,%2"
14001   [(set_attr "type" "qmul")
14002    (set_attr "size" "128")])
14004 (define_insn "div<mode>3"
14005   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14006         (div:IEEE128
14007          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14008          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14009   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14010   "xsdivqp %0,%1,%2"
14011   [(set_attr "type" "vecdiv")
14012    (set_attr "size" "128")])
14014 (define_insn "sqrt<mode>2"
14015   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14016         (sqrt:IEEE128
14017          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14018   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14019    "xssqrtqp %0,%1"
14020   [(set_attr "type" "vecdiv")
14021    (set_attr "size" "128")])
14023 (define_expand "copysign<mode>3"
14024   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14025    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14026    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14027   "FLOAT128_IEEE_P (<MODE>mode)"
14029   if (TARGET_FLOAT128_HW)
14030     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14031                                          operands[2]));
14032   else
14033     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14034                                          operands[2]));
14035   DONE;
14038 (define_insn "copysign<mode>3_hard"
14039   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14040         (unspec:IEEE128
14041          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14042           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14043          UNSPEC_COPYSIGN))]
14044   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14045    "xscpsgnqp %0,%2,%1"
14046   [(set_attr "type" "vecmove")
14047    (set_attr "size" "128")])
14049 (define_insn "copysign<mode>3_soft"
14050   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14051         (unspec:IEEE128
14052          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14053           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14054          UNSPEC_COPYSIGN))
14055    (clobber (match_scratch:IEEE128 3 "=&v"))]
14056   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14057    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14058   [(set_attr "type" "veccomplex")
14059    (set_attr "length" "8")])
14061 (define_insn "@neg<mode>2_hw"
14062   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14063         (neg:IEEE128
14064          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14065   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14066   "xsnegqp %0,%1"
14067   [(set_attr "type" "vecmove")
14068    (set_attr "size" "128")])
14071 (define_insn "@abs<mode>2_hw"
14072   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14073         (abs:IEEE128
14074          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14075   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14076   "xsabsqp %0,%1"
14077   [(set_attr "type" "vecmove")
14078    (set_attr "size" "128")])
14081 (define_insn "*nabs<mode>2_hw"
14082   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14083         (neg:IEEE128
14084          (abs:IEEE128
14085           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14086   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14087   "xsnabsqp %0,%1"
14088   [(set_attr "type" "vecmove")
14089    (set_attr "size" "128")])
14091 ;; Initially don't worry about doing fusion
14092 (define_insn "fma<mode>4_hw"
14093   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14094         (fma:IEEE128
14095          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14096          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14097          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14098   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14099   "xsmaddqp %0,%1,%2"
14100   [(set_attr "type" "qmul")
14101    (set_attr "size" "128")])
14103 (define_insn "*fms<mode>4_hw"
14104   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14105         (fma:IEEE128
14106          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14107          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14108          (neg:IEEE128
14109           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14110   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14111   "xsmsubqp %0,%1,%2"
14112   [(set_attr "type" "qmul")
14113    (set_attr "size" "128")])
14115 (define_insn "*nfma<mode>4_hw"
14116   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14117         (neg:IEEE128
14118          (fma:IEEE128
14119           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14120           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14121           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14122   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14123   "xsnmaddqp %0,%1,%2"
14124   [(set_attr "type" "qmul")
14125    (set_attr "size" "128")])
14127 (define_insn "*nfms<mode>4_hw"
14128   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14129         (neg:IEEE128
14130          (fma:IEEE128
14131           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14132           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14133           (neg:IEEE128
14134            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14135   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14136   "xsnmsubqp %0,%1,%2"
14137   [(set_attr "type" "qmul")
14138    (set_attr "size" "128")])
14140 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14141   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14142         (float_extend:IEEE128
14143          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14144   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14145   "xscvdpqp %0,%1"
14146   [(set_attr "type" "vecfloat")
14147    (set_attr "size" "128")])
14149 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14150 ;; point is a simple copy.
14151 (define_insn_and_split "extendkftf2"
14152   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14153         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14154   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14155   "@
14156    #
14157    xxlor %x0,%x1,%x1"
14158   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14159   [(const_int 0)]
14161   emit_note (NOTE_INSN_DELETED);
14162   DONE;
14164   [(set_attr "type" "*,veclogical")
14165    (set_attr "length" "0,4")])
14167 (define_insn_and_split "trunctfkf2"
14168   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14169         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14170   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14171   "@
14172    #
14173    xxlor %x0,%x1,%x1"
14174   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14175   [(const_int 0)]
14177   emit_note (NOTE_INSN_DELETED);
14178   DONE;
14180   [(set_attr "type" "*,veclogical")
14181    (set_attr "length" "0,4")])
14183 (define_insn "trunc<mode>df2_hw"
14184   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14185         (float_truncate:DF
14186          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14187   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14188   "xscvqpdp %0,%1"
14189   [(set_attr "type" "vecfloat")
14190    (set_attr "size" "128")])
14192 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14193 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14194 ;; conversion
14195 (define_insn_and_split "trunc<mode>sf2_hw"
14196   [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14197         (float_truncate:SF
14198          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14199    (clobber (match_scratch:DF 2 "=v"))]
14200   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14201   "#"
14202   "&& 1"
14203   [(set (match_dup 2)
14204         (unspec:DF [(match_dup 1)]
14205                    UNSPEC_TRUNC_ROUND_TO_ODD))
14206    (set (match_dup 0)
14207         (float_truncate:SF (match_dup 2)))]
14209   if (GET_CODE (operands[2]) == SCRATCH)
14210     operands[2] = gen_reg_rtx (DFmode);
14212   [(set_attr "type" "vecfloat")
14213    (set_attr "length" "8")
14214    (set_attr "isa" "p8v")])
14216 ;; Conversion between IEEE 128-bit and integer types
14218 ;; The fix function for DImode and SImode was declared earlier as a
14219 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14220 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14221 ;; unless we have the IEEE 128-bit hardware.
14223 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14224 ;; to provide a GPR target that used direct move and a conversion in the GPR
14225 ;; which works around QImode/HImode not being allowed in vector registers in
14226 ;; ISA 2.07 (power8).
14227 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14228   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14229         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14230   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14231   "xscvqp<su><wd>z %0,%1"
14232   [(set_attr "type" "vecfloat")
14233    (set_attr "size" "128")])
14235 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14236   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14237         (any_fix:QHI
14238          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14239   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14240   "xscvqp<su>wz %0,%1"
14241   [(set_attr "type" "vecfloat")
14242    (set_attr "size" "128")])
14244 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14245 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14246 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14247   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14248         (any_fix:QHSI
14249          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14250    (clobber (match_scratch:QHSI 2 "=v"))]
14251   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14252   "#"
14253   "&& reload_completed"
14254   [(set (match_dup 2)
14255         (any_fix:QHSI (match_dup 1)))
14256    (set (match_dup 0)
14257         (match_dup 2))])
14259 (define_insn "float_<mode>di2_hw"
14260   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14261         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14262   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14263   "xscvsdqp %0,%1"
14264   [(set_attr "type" "vecfloat")
14265    (set_attr "size" "128")])
14267 (define_insn_and_split "float_<mode>si2_hw"
14268   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14269         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14270    (clobber (match_scratch:DI 2 "=v"))]
14271   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14272   "#"
14273   "&& 1"
14274   [(set (match_dup 2)
14275         (sign_extend:DI (match_dup 1)))
14276    (set (match_dup 0)
14277         (float:IEEE128 (match_dup 2)))]
14279   if (GET_CODE (operands[2]) == SCRATCH)
14280     operands[2] = gen_reg_rtx (DImode);
14282   if (MEM_P (operands[1]))
14283     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14286 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14287   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14288         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14289    (clobber (match_scratch:DI 2 "=X,r,X"))]
14290   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14291   "#"
14292   "&& reload_completed"
14293   [(const_int 0)]
14295   rtx dest = operands[0];
14296   rtx src = operands[1];
14297   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14299   if (altivec_register_operand (src, <QHI:MODE>mode))
14300     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14301   else if (int_reg_operand (src, <QHI:MODE>mode))
14302     {
14303       rtx ext_di = operands[2];
14304       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14305       emit_move_insn (dest_di, ext_di);
14306     }
14307   else if (MEM_P (src))
14308     {
14309       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14310       emit_move_insn (dest_qhi, src);
14311       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14312     }
14313   else
14314     gcc_unreachable ();
14316   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14317   DONE;
14319   [(set_attr "length" "8,12,12")
14320    (set_attr "type" "vecfloat")
14321    (set_attr "size" "128")])
14323 (define_insn "floatuns_<mode>di2_hw"
14324   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14325         (unsigned_float:IEEE128
14326          (match_operand:DI 1 "altivec_register_operand" "v")))]
14327   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14328   "xscvudqp %0,%1"
14329   [(set_attr "type" "vecfloat")
14330    (set_attr "size" "128")])
14332 (define_insn_and_split "floatuns_<mode>si2_hw"
14333   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14334         (unsigned_float:IEEE128
14335          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14336    (clobber (match_scratch:DI 2 "=v"))]
14337   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14338   "#"
14339   "&& 1"
14340   [(set (match_dup 2)
14341         (zero_extend:DI (match_dup 1)))
14342    (set (match_dup 0)
14343         (float:IEEE128 (match_dup 2)))]
14345   if (GET_CODE (operands[2]) == SCRATCH)
14346     operands[2] = gen_reg_rtx (DImode);
14348   if (MEM_P (operands[1]))
14349     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14352 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14353   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14354         (unsigned_float:IEEE128
14355          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14356    (clobber (match_scratch:DI 2 "=X,r,X"))]
14357   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14358   "#"
14359   "&& reload_completed"
14360   [(const_int 0)]
14362   rtx dest = operands[0];
14363   rtx src = operands[1];
14364   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14366   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14367     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14368   else if (int_reg_operand (src, <QHI:MODE>mode))
14369     {
14370       rtx ext_di = operands[2];
14371       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14372       emit_move_insn (dest_di, ext_di);
14373     }
14374   else
14375     gcc_unreachable ();
14377   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14378   DONE;
14380   [(set_attr "length" "8,12,8")
14381    (set_attr "type" "vecfloat")
14382    (set_attr "size" "128")])
14384 ;; IEEE 128-bit round to integer built-in functions
14385 (define_insn "floor<mode>2"
14386   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14387         (unspec:IEEE128
14388          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14389          UNSPEC_FRIM))]
14390   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14391   "xsrqpi 1,%0,%1,3"
14392   [(set_attr "type" "vecfloat")
14393    (set_attr "size" "128")])
14395 (define_insn "ceil<mode>2"
14396   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14397         (unspec:IEEE128
14398          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14399          UNSPEC_FRIP))]
14400   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401   "xsrqpi 1,%0,%1,2"
14402   [(set_attr "type" "vecfloat")
14403    (set_attr "size" "128")])
14405 (define_insn "btrunc<mode>2"
14406   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14407         (unspec:IEEE128
14408          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14409          UNSPEC_FRIZ))]
14410   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14411   "xsrqpi 1,%0,%1,1"
14412   [(set_attr "type" "vecfloat")
14413    (set_attr "size" "128")])
14415 (define_insn "round<mode>2"
14416   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14417         (unspec:IEEE128
14418          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14419          UNSPEC_FRIN))]
14420   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14421   "xsrqpi 0,%0,%1,0"
14422   [(set_attr "type" "vecfloat")
14423    (set_attr "size" "128")])
14425 ;; IEEE 128-bit instructions with round to odd semantics
14426 (define_insn "add<mode>3_odd"
14427   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14428         (unspec:IEEE128
14429          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14430           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14431          UNSPEC_ADD_ROUND_TO_ODD))]
14432   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14433   "xsaddqpo %0,%1,%2"
14434   [(set_attr "type" "vecfloat")
14435    (set_attr "size" "128")])
14437 (define_insn "sub<mode>3_odd"
14438   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14439         (unspec:IEEE128
14440          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14441           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14442          UNSPEC_SUB_ROUND_TO_ODD))]
14443   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14444   "xssubqpo %0,%1,%2"
14445   [(set_attr "type" "vecfloat")
14446    (set_attr "size" "128")])
14448 (define_insn "mul<mode>3_odd"
14449   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14450         (unspec:IEEE128
14451          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14452           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14453          UNSPEC_MUL_ROUND_TO_ODD))]
14454   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14455   "xsmulqpo %0,%1,%2"
14456   [(set_attr "type" "qmul")
14457    (set_attr "size" "128")])
14459 (define_insn "div<mode>3_odd"
14460   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14461         (unspec:IEEE128
14462          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14463           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14464          UNSPEC_DIV_ROUND_TO_ODD))]
14465   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14466   "xsdivqpo %0,%1,%2"
14467   [(set_attr "type" "vecdiv")
14468    (set_attr "size" "128")])
14470 (define_insn "sqrt<mode>2_odd"
14471   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14472         (unspec:IEEE128
14473          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14474          UNSPEC_SQRT_ROUND_TO_ODD))]
14475   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14476    "xssqrtqpo %0,%1"
14477   [(set_attr "type" "vecdiv")
14478    (set_attr "size" "128")])
14480 (define_insn "fma<mode>4_odd"
14481   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14482         (unspec:IEEE128
14483          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14484           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14485           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14486          UNSPEC_FMA_ROUND_TO_ODD))]
14487   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14488   "xsmaddqpo %0,%1,%2"
14489   [(set_attr "type" "qmul")
14490    (set_attr "size" "128")])
14492 (define_insn "*fms<mode>4_odd"
14493   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14494         (unspec:IEEE128
14495          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14496           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14497           (neg:IEEE128
14498            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14499          UNSPEC_FMA_ROUND_TO_ODD))]
14500   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14501   "xsmsubqpo %0,%1,%2"
14502   [(set_attr "type" "qmul")
14503    (set_attr "size" "128")])
14505 (define_insn "*nfma<mode>4_odd"
14506   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14507         (neg:IEEE128
14508          (unspec:IEEE128
14509           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14510            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14511            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14512           UNSPEC_FMA_ROUND_TO_ODD)))]
14513   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14514   "xsnmaddqpo %0,%1,%2"
14515   [(set_attr "type" "qmul")
14516    (set_attr "size" "128")])
14518 (define_insn "*nfms<mode>4_odd"
14519   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14520         (neg:IEEE128
14521          (unspec:IEEE128
14522           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14523            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14524            (neg:IEEE128
14525             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14526           UNSPEC_FMA_ROUND_TO_ODD)))]
14527   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14528   "xsnmsubqpo %0,%1,%2"
14529   [(set_attr "type" "qmul")
14530    (set_attr "size" "128")])
14532 (define_insn "trunc<mode>df2_odd"
14533   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14534         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14535                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14536   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14537   "xscvqpdpo %0,%1"
14538   [(set_attr "type" "vecfloat")
14539    (set_attr "size" "128")])
14541 ;; IEEE 128-bit comparisons
14542 (define_insn "*cmp<mode>_hw"
14543   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14544         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14545                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14546   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14547    "xscmpuqp %0,%1,%2"
14548   [(set_attr "type" "veccmp")
14549    (set_attr "size" "128")])
14551 ;; Miscellaneous ISA 3.0 (power9) instructions
14553 (define_insn "darn_32"
14554   [(set (match_operand:SI 0 "register_operand" "=r")
14555         (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14556   "TARGET_P9_MISC"
14557   "darn %0,0"
14558   [(set_attr "type" "integer")])
14560 (define_insn "darn_raw"
14561   [(set (match_operand:DI 0 "register_operand" "=r")
14562         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14563   "TARGET_P9_MISC && TARGET_64BIT"
14564   "darn %0,2"
14565   [(set_attr "type" "integer")])
14567 (define_insn "darn"
14568   [(set (match_operand:DI 0 "register_operand" "=r")
14569         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14570   "TARGET_P9_MISC && TARGET_64BIT"
14571   "darn %0,1"
14572   [(set_attr "type" "integer")])
14574 ;; Test byte within range.
14576 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14577 ;; represents a byte whose value is ignored in this context and
14578 ;; vv, the least significant byte, holds the byte value that is to
14579 ;; be tested for membership within the range specified by operand 2.
14580 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14582 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14583 ;; vv <= hi.  Otherwise, set register operand 0 to 0.
14585 ;; Though the instructions to which this expansion maps operate on
14586 ;; 64-bit registers, the current implementation only operates on
14587 ;; SI-mode operands as the high-order bits provide no information
14588 ;; that is not already available in the low-order bits.  To avoid the
14589 ;; costs of data widening operations, future enhancements might allow
14590 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14591 (define_expand "cmprb"
14592   [(set (match_dup 3)
14593         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14594                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14595          UNSPEC_CMPRB))
14596    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14597         (if_then_else:SI (lt (match_dup 3)
14598                              (const_int 0))
14599                          (const_int -1)
14600                          (if_then_else (gt (match_dup 3)
14601                                            (const_int 0))
14602                                        (const_int 1)
14603                                        (const_int 0))))]
14604   "TARGET_P9_MISC"
14606   operands[3] = gen_reg_rtx (CCmode);
14609 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14610 ;; represents a byte whose value is ignored in this context and
14611 ;; vv, the least significant byte, holds the byte value that is to
14612 ;; be tested for membership within the range specified by operand 2.
14613 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14615 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14616 ;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14617 ;; 3 bits of the target CR register are all set to 0.
14618 (define_insn "*cmprb_internal"
14619   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14620         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14621                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14622          UNSPEC_CMPRB))]
14623   "TARGET_P9_MISC"
14624   "cmprb %0,0,%1,%2"
14625   [(set_attr "type" "logical")])
14627 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14628 ;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14629 ;; if the GT bit (0x4) of condition register operand 1 is on.
14630 ;; Otherwise, set operand 0 to 0.  Note that the result stored into
14631 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14632 ;; within condition register operand 1.
14633 (define_insn "setb_signed"
14634    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14635          (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14636                               (const_int 0))
14637                           (const_int -1)
14638                           (if_then_else (gt (match_dup 1)
14639                                             (const_int 0))
14640                                         (const_int 1)
14641                                         (const_int 0))))]
14642   "TARGET_P9_MISC"
14643   "setb %0,%1"
14644   [(set_attr "type" "logical")])
14646 (define_insn "setb_unsigned"
14647    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14648          (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14649                               (const_int 0))
14650                           (const_int -1)
14651                           (if_then_else (gtu (match_dup 1)
14652                                             (const_int 0))
14653                                         (const_int 1)
14654                                         (const_int 0))))]
14655   "TARGET_P9_MISC"
14656   "setb %0,%1"
14657   [(set_attr "type" "logical")])
14659 ;; Test byte within two ranges.
14661 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14662 ;; represents a byte whose value is ignored in this context and
14663 ;; vv, the least significant byte, holds the byte value that is to
14664 ;; be tested for membership within the range specified by operand 2.
14665 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14667 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14668 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14669 ;; operand 0 to 0.
14671 ;; Though the instructions to which this expansion maps operate on
14672 ;; 64-bit registers, the current implementation only operates on
14673 ;; SI-mode operands as the high-order bits provide no information
14674 ;; that is not already available in the low-order bits.  To avoid the
14675 ;; costs of data widening operations, future enhancements might allow
14676 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14677 (define_expand "cmprb2"
14678   [(set (match_dup 3)
14679         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14680                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14681          UNSPEC_CMPRB2))
14682    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14683         (if_then_else:SI (lt (match_dup 3)
14684                              (const_int 0))
14685                          (const_int -1)
14686                          (if_then_else (gt (match_dup 3)
14687                                            (const_int 0))
14688                                        (const_int 1)
14689                                        (const_int 0))))]
14690   "TARGET_P9_MISC"
14692   operands[3] = gen_reg_rtx (CCmode);
14695 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14696 ;; represents a byte whose value is ignored in this context and
14697 ;; vv, the least significant byte, holds the byte value that is to
14698 ;; be tested for membership within the ranges specified by operand 2.
14699 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14701 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14702 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14703 ;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14704 ;; CR register are all set to 0.
14705 (define_insn "*cmprb2_internal"
14706   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14707         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14708                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14709          UNSPEC_CMPRB2))]
14710   "TARGET_P9_MISC"
14711   "cmprb %0,1,%1,%2"
14712   [(set_attr "type" "logical")])
14714 ;; Test byte membership within set of 8 bytes.
14716 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14717 ;; represents a byte whose value is ignored in this context and
14718 ;; vv, the least significant byte, holds the byte value that is to
14719 ;; be tested for membership within the set specified by operand 2.
14720 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14722 ;; Return in target register operand 0 a value of 1 if vv equals one
14723 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14724 ;; register operand 0 to 0.  Note that the 8 byte values held within
14725 ;; operand 2 need not be unique.
14727 ;; Though the instructions to which this expansion maps operate on
14728 ;; 64-bit registers, the current implementation requires that operands
14729 ;; 0 and 1 have mode SI as the high-order bits provide no information
14730 ;; that is not already available in the low-order bits.  To avoid the
14731 ;; costs of data widening operations, future enhancements might allow
14732 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14733 (define_expand "cmpeqb"
14734   [(set (match_dup 3)
14735         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14736                     (match_operand:DI 2 "gpc_reg_operand" "r")]
14737          UNSPEC_CMPEQB))
14738    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14739         (if_then_else:SI (lt (match_dup 3)
14740                              (const_int 0))
14741                          (const_int -1)
14742                          (if_then_else (gt (match_dup 3)
14743                                            (const_int 0))
14744                                        (const_int 1)
14745                                        (const_int 0))))]
14746   "TARGET_P9_MISC && TARGET_64BIT"
14748   operands[3] = gen_reg_rtx (CCmode);
14751 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14752 ;; represents a byte whose value is ignored in this context and
14753 ;; vv, the least significant byte, holds the byte value that is to
14754 ;; be tested for membership within the set specified by operand 2.
14755 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14757 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14758 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14759 ;; set the GT bit to zero.  The other 3 bits of the target CR register
14760 ;; are all set to 0.
14761 (define_insn "*cmpeqb_internal"
14762   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14763          (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14764                      (match_operand:DI 2 "gpc_reg_operand" "r")]
14765           UNSPEC_CMPEQB))]
14766   "TARGET_P9_MISC && TARGET_64BIT"
14767   "cmpeqb %0,%1,%2"
14768   [(set_attr "type" "logical")])
14771 (include "sync.md")
14772 (include "vector.md")
14773 (include "vsx.md")
14774 (include "altivec.md")
14775 (include "dfp.md")
14776 (include "crypto.md")
14777 (include "htm.md")