[gcc]
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobbc8e52d6f6aadcdd3f58f9abeb6fe3e0257868bf
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2016 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    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (SPE_ACC_REGNO               111)
54    (SPEFSCR_REGNO               112)
55    (FRAME_POINTER_REGNUM        113)
56    (TFHAR_REGNO                 114)
57    (TFIAR_REGNO                 115)
58    (TEXASR_REGNO                116)
59    (FIRST_SPE_HIGH_REGNO        117)
60    (LAST_SPE_HIGH_REGNO         148)
61   ])
64 ;; UNSPEC usage
67 (define_c_enum "unspec"
68   [UNSPEC_FRSP                  ; frsp for POWER machines
69    UNSPEC_PROBE_STACK           ; probe stack memory reference
70    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
71    UNSPEC_TOC                   ; address of the TOC (more-or-less)
72    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
73    UNSPEC_MOVSI_GOT
74    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
75    UNSPEC_FCTIWZ
76    UNSPEC_FRIM
77    UNSPEC_FRIN
78    UNSPEC_FRIP
79    UNSPEC_FRIZ
80    UNSPEC_XSRDPI
81    UNSPEC_LD_MPIC               ; load_macho_picbase
82    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
83    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
84    UNSPEC_TLSGD
85    UNSPEC_TLSLD
86    UNSPEC_MOVESI_FROM_CR
87    UNSPEC_MOVESI_TO_CR
88    UNSPEC_TLSDTPREL
89    UNSPEC_TLSDTPRELHA
90    UNSPEC_TLSDTPRELLO
91    UNSPEC_TLSGOTDTPREL
92    UNSPEC_TLSTPREL
93    UNSPEC_TLSTPRELHA
94    UNSPEC_TLSTPRELLO
95    UNSPEC_TLSGOTTPREL
96    UNSPEC_TLSTLS
97    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
98    UNSPEC_MV_CR_GT              ; move_from_CR_gt_bit
99    UNSPEC_STFIWX
100    UNSPEC_POPCNTB
101    UNSPEC_FRES
102    UNSPEC_SP_SET
103    UNSPEC_SP_TEST
104    UNSPEC_SYNC
105    UNSPEC_LWSYNC
106    UNSPEC_SYNC_OP
107    UNSPEC_ATOMIC
108    UNSPEC_CMPXCHG
109    UNSPEC_XCHG
110    UNSPEC_AND
111    UNSPEC_DLMZB
112    UNSPEC_DLMZB_CR
113    UNSPEC_DLMZB_STRLEN
114    UNSPEC_RSQRT
115    UNSPEC_TOCREL
116    UNSPEC_MACHOPIC_OFFSET
117    UNSPEC_BPERM
118    UNSPEC_COPYSIGN
119    UNSPEC_PARITY
120    UNSPEC_FCTIW
121    UNSPEC_FCTID
122    UNSPEC_LFIWAX
123    UNSPEC_LFIWZX
124    UNSPEC_FCTIWUZ
125    UNSPEC_NOP
126    UNSPEC_GRP_END_NOP
127    UNSPEC_P8V_FMRGOW
128    UNSPEC_P8V_MTVSRWZ
129    UNSPEC_P8V_RELOAD_FROM_GPR
130    UNSPEC_P8V_MTVSRD
131    UNSPEC_P8V_XXPERMDI
132    UNSPEC_P8V_RELOAD_FROM_VSX
133    UNSPEC_ADDG6S
134    UNSPEC_CDTBCD
135    UNSPEC_CBCDTD
136    UNSPEC_DIVE
137    UNSPEC_DIVEO
138    UNSPEC_DIVEU
139    UNSPEC_DIVEUO
140    UNSPEC_UNPACK_128BIT
141    UNSPEC_PACK_128BIT
142    UNSPEC_LSQ
143    UNSPEC_FUSION_GPR
144    UNSPEC_STACK_CHECK
145    UNSPEC_FUSION_P9
146    UNSPEC_FUSION_ADDIS
147    UNSPEC_ROUND_TO_ODD
148    UNSPEC_IEEE128_MOVE
149    UNSPEC_IEEE128_CONVERT
150    UNSPEC_SIGNBIT
151    UNSPEC_DOLOOP
152   ])
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
159   [UNSPECV_BLOCK
160    UNSPECV_LL                   ; load-locked
161    UNSPECV_SC                   ; store-conditional
162    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
163    UNSPECV_EH_RR                ; eh_reg_restore
164    UNSPECV_ISYNC                ; isync instruction
165    UNSPECV_MFTB                 ; move from time base
166    UNSPECV_NLGR                 ; non-local goto receiver
167    UNSPECV_MFFS                 ; Move from FPSCR
168    UNSPECV_MTFSF                ; Move to FPSCR Fields
169    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
170   ])
173 ;; Define an insn type attribute.  This is used in function unit delay
174 ;; computations.
175 (define_attr "type"
176   "integer,two,three,
177    add,logical,shift,insert,
178    mul,halfmul,div,
179    exts,cntlz,popcnt,isel,
180    load,store,fpload,fpstore,vecload,vecstore,
181    cmp,
182    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
185    brinc,
186    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188    veclogical,veccmpfx,vecexts,vecmove,
189    htm,htmsimple,dfp"
190   (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that.  If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210   (if_then_else (ior (match_operand 0 "indexed_address_mem")
211                      (match_operand 1 "indexed_address_mem"))
212                 (const_string "yes")
213                 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns.  See the comments for "indexed".
217 (define_attr "update" "no,yes"
218   (if_then_else (ior (match_operand 0 "update_address_mem")
219                      (match_operand 1 "update_address_mem"))
220                 (const_string "yes")
221                 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
224 ;; register?
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231   (if_then_else (and (eq_attr "type" "shift")
232                      (eq_attr "maybe_var_shift" "yes"))
233                 (if_then_else (match_operand 2 "gpc_reg_operand")
234                               (const_string "yes")
235                               (const_string "no"))
236                 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248   (if_then_else (eq_attr "type" "branch")
249                 (if_then_else (and (ge (minus (match_dup 0) (pc))
250                                        (const_int -32768))
251                                    (lt (minus (match_dup 0) (pc))
252                                        (const_int 32764)))
253                               (const_int 4)
254                               (const_int 8))
255                 (const_int 4)))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
259 (define_attr "cpu"
260   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261    ppc750,ppc7400,ppc7450,
262    ppc403,ppc405,ppc440,ppc476,
263    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264    power4,power5,power6,power7,power8,power9,
265    rs64a,mpccore,cell,ppca2,titan"
266   (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273                           (eq_attr "dot" "yes"))
274                      (and (eq_attr "type" "load")
275                           (eq_attr "sign_extend" "yes"))
276                      (and (eq_attr "type" "shift")
277                           (eq_attr "var_shift" "yes")))
278                 (const_string "always")
279                 (const_string "not")))
281 (automata_option "ndfa")
283 (include "rs64.md")
284 (include "mpc.md")
285 (include "40x.md")
286 (include "440.md")
287 (include "476.md")
288 (include "601.md")
289 (include "603.md")
290 (include "6xx.md")
291 (include "7xx.md")
292 (include "7450.md")
293 (include "8540.md")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
297 (include "e5500.md")
298 (include "e6500.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
305 (include "cell.md")
306 (include "xfpu.md")
307 (include "a2.md")
308 (include "titan.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
316 ;; Mode iterators
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Everything we can extend QImode to.
329 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
331 ; Everything we can extend HImode to.
332 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend SImode to.
335 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
337 ; QImode or HImode for small atomic ops
338 (define_mode_iterator QHI [QI HI])
340 ; QImode, HImode, SImode for fused ops only for GPR loads
341 (define_mode_iterator QHSI [QI HI SI])
343 ; HImode or SImode for sign extended fusion ops
344 (define_mode_iterator HSI [HI SI])
346 ; SImode or DImode, even if DImode doesn't fit in GPRs.
347 (define_mode_iterator SDI [SI DI])
349 ; Types that can be fused with an ADDIS instruction to load or store a GPR
350 ; register that has reg+offset addressing.
351 (define_mode_iterator GPR_FUSION [QI
352                                   HI
353                                   SI
354                                   (DI   "TARGET_POWERPC64")
355                                   SF
356                                   (DF   "TARGET_POWERPC64")])
358 ; Types that can be fused with an ADDIS instruction to load or store a FPR
359 ; register that has reg+offset addressing.
360 (define_mode_iterator FPR_FUSION [DI SF DF])
362 ; The size of a pointer.  Also, the size of the value that a record-condition
363 ; (one with a '.') will compare; and the size used for arithmetic carries.
364 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
366 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
367 ; PTImode is GPR only)
368 (define_mode_iterator TI2 [TI PTI])
370 ; Any hardware-supported floating-point mode
371 (define_mode_iterator FP [
372   (SF "TARGET_HARD_FLOAT 
373    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
374   (DF "TARGET_HARD_FLOAT 
375    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
376   (TF "TARGET_HARD_FLOAT
377    && (TARGET_FPRS || TARGET_E500_DOUBLE)
378    && TARGET_LONG_DOUBLE_128")
379   (IF "TARGET_LONG_DOUBLE_128")
380   (KF "TARGET_FLOAT128_TYPE")
381   (DD "TARGET_DFP")
382   (TD "TARGET_DFP")])
384 ; Any fma capable floating-point mode.
385 (define_mode_iterator FMA_F [
386   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
387   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
388        || VECTOR_UNIT_VSX_P (DFmode)")
389   (V2SF "TARGET_PAIRED_FLOAT")
390   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
391   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
392   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
393   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
394   ])
396 ; Floating point move iterators to combine binary and decimal moves
397 (define_mode_iterator FMOVE32 [SF SD])
398 (define_mode_iterator FMOVE64 [DF DD])
399 (define_mode_iterator FMOVE64X [DI DF DD])
400 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
401                                 (IF "TARGET_LONG_DOUBLE_128")
402                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
404 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
405                                     (IF "FLOAT128_2REG_P (IFmode)")
406                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
408 ; Iterators for 128 bit types for direct move
409 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
410                                     (V16QI "")
411                                     (V8HI  "")
412                                     (V4SI  "")
413                                     (V4SF  "")
414                                     (V2DI  "")
415                                     (V2DF  "")
416                                     (V1TI  "")
417                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
418                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
420 ; Iterator for 128-bit VSX types for pack/unpack
421 (define_mode_iterator FMOVE128_VSX [V1TI KF])
423 ; Whether a floating point move is ok, don't allow SD without hardware FP
424 (define_mode_attr fmove_ok [(SF "")
425                             (DF "")
426                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
427                             (DD "")])
429 ; Convert REAL_VALUE to the appropriate bits
430 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
431                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
432                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
433                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
435 ; Whether 0.0 has an all-zero bit pattern
436 (define_mode_attr zero_fp [(SF "j")
437                            (DF "j")
438                            (TF "j")
439                            (IF "j")
440                            (KF "j")
441                            (SD "wn")
442                            (DD "wn")
443                            (TD "wn")])
445 ; Definitions for load to 32-bit fpr register
446 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
447 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
448 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
449 (define_mode_attr f32_lm2 [(SF "wY")              (SD "wn")])
450 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
451 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
452 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
454 ; Definitions for store from 32-bit fpr register
455 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
456 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
457 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
458 (define_mode_attr f32_sm2 [(SF "wY")               (SD "wn")])
459 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
460 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
461 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwx %x1,%y0")])
463 ; Definitions for 32-bit fpr direct move
464 ; At present, the decimal modes are not allowed in the traditional altivec
465 ; registers, so restrict the constraints to just the traditional FPRs.
466 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
468 ; Definitions for 32-bit VSX
469 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
471 ; Definitions for 32-bit use of altivec registers
472 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
474 ; Definitions for 64-bit VSX
475 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
477 ; Definitions for 64-bit direct move
478 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
480 ; Definitions for 64-bit use of altivec registers
481 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
483 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
484 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
486 ; These modes do not fit in integer registers in 32-bit mode.
487 ; but on e500v2, the gpr are 64 bit registers
488 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
490 ; Iterator for reciprocal estimate instructions
491 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
493 ; Iterator for just SF/DF
494 (define_mode_iterator SFDF [SF DF])
496 ; Like SFDF, but a different name to match conditional move where the
497 ; comparison operands may be a different mode than the input operands.
498 (define_mode_iterator SFDF2 [SF DF])
500 ; Iterator for 128-bit floating point that uses the IBM double-double format
501 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
502                               (TF "FLOAT128_IBM_P (TFmode)")])
504 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
505 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
506                                (TF "FLOAT128_IEEE_P (TFmode)")])
508 ; Iterator for 128-bit floating point
509 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
510                                 (IF "TARGET_FLOAT128_TYPE")
511                                 (TF "TARGET_LONG_DOUBLE_128")])
513 ; Iterator for signbit on 64-bit machines with direct move
514 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
515                                (TF "FLOAT128_VECTOR_P (TFmode)")])
517 (define_mode_attr Fsignbit      [(KF "wa")
518                                  (TF "wa")])
520 ; Iterator for ISA 3.0 supported floating point types
521 (define_mode_iterator FP_ISA3 [SF
522                                DF
523                                (KF "FLOAT128_IEEE_P (KFmode)")
524                                (TF "FLOAT128_IEEE_P (TFmode)")])
526 ; SF/DF suffix for traditional floating instructions
527 (define_mode_attr Ftrad         [(SF "s") (DF "")])
529 ; SF/DF suffix for VSX instructions
530 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
532 ; SF/DF constraint for arithmetic on traditional floating point registers
533 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
535 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
536 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
537 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
538 ; format.
539 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
541 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
542 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
543 ; instructions added in ISA 2.07 (power8)
544 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
546 ; SF/DF constraint for arithmetic on altivec registers
547 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
549 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
550 (define_mode_attr Fs            [(SF "s")  (DF "d")])
552 ; FRE/FRES support
553 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
554 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
556 ; Conditional returns.
557 (define_code_iterator any_return [return simple_return])
558 (define_code_attr return_pred [(return "direct_return ()")
559                                (simple_return "1")])
560 (define_code_attr return_str [(return "") (simple_return "simple_")])
562 ; Logical operators.
563 (define_code_iterator iorxor [ior xor])
565 ; Signed/unsigned variants of ops.
566 (define_code_iterator any_extend        [sign_extend zero_extend])
567 (define_code_iterator any_fix           [fix unsigned_fix])
568 (define_code_iterator any_float         [float unsigned_float])
570 (define_code_attr u  [(sign_extend      "")
571                       (zero_extend      "u")])
573 (define_code_attr su [(sign_extend      "s")
574                       (zero_extend      "u")
575                       (fix              "s")
576                       (unsigned_fix     "s")
577                       (float            "s")
578                       (unsigned_float   "u")])
580 (define_code_attr az [(sign_extend      "a")
581                       (zero_extend      "z")
582                       (fix              "a")
583                       (unsigned_fix     "z")
584                       (float            "a")
585                       (unsigned_float   "z")])
587 (define_code_attr uns [(fix             "")
588                        (unsigned_fix    "uns")
589                        (float           "")
590                        (unsigned_float  "uns")])
592 ; Various instructions that come in SI and DI forms.
593 ; A generic w/d attribute, for things like cmpw/cmpd.
594 (define_mode_attr wd [(QI    "b")
595                       (HI    "h")
596                       (SI    "w")
597                       (DI    "d")
598                       (V16QI "b")
599                       (V8HI  "h")
600                       (V4SI  "w")
601                       (V2DI  "d")
602                       (V1TI  "q")
603                       (TI    "q")])
605 ;; How many bits in this mode?
606 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
608 ; DImode bits
609 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
611 ;; ISEL/ISEL64 target selection
612 (define_mode_attr sel [(SI "") (DI "64")])
614 ;; Bitmask for shift instructions
615 (define_mode_attr hH [(SI "h") (DI "H")])
617 ;; A mode twice the size of the given mode
618 (define_mode_attr dmode [(SI "di") (DI "ti")])
619 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
621 ;; Suffix for reload patterns
622 (define_mode_attr ptrsize [(SI "32bit")
623                            (DI "64bit")])
625 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
626                             (DI "TARGET_64BIT")])
628 (define_mode_attr mptrsize [(SI "si")
629                             (DI "di")])
631 (define_mode_attr ptrload [(SI "lwz")
632                            (DI "ld")])
634 (define_mode_attr ptrm [(SI "m")
635                         (DI "Y")])
637 (define_mode_attr rreg [(SF   "f")
638                         (DF   "ws")
639                         (TF   "f")
640                         (TD   "f")
641                         (V4SF "wf")
642                         (V2DF "wd")])
644 (define_mode_attr rreg2 [(SF   "f")
645                          (DF   "d")])
647 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
648                                  (DF "TARGET_FCFID")])
650 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
651                                 (DF "TARGET_E500_DOUBLE")])
653 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
654                                 (DF "TARGET_DOUBLE_FLOAT")])
656 ;; Mode iterator for logical operations on 128-bit types
657 (define_mode_iterator BOOL_128          [TI
658                                          PTI
659                                          (V16QI "TARGET_ALTIVEC")
660                                          (V8HI  "TARGET_ALTIVEC")
661                                          (V4SI  "TARGET_ALTIVEC")
662                                          (V4SF  "TARGET_ALTIVEC")
663                                          (V2DI  "TARGET_ALTIVEC")
664                                          (V2DF  "TARGET_ALTIVEC")
665                                          (V1TI  "TARGET_ALTIVEC")])
667 ;; For the GPRs we use 3 constraints for register outputs, two that are the
668 ;; same as the output register, and a third where the output register is an
669 ;; early clobber, so we don't have to deal with register overlaps.  For the
670 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
671 ;; either.
673 ;; Mode attribute for boolean operation register constraints for output
674 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
675                                          (PTI   "&r,r,r")
676                                          (V16QI "wa,v,&?r,?r,?r")
677                                          (V8HI  "wa,v,&?r,?r,?r")
678                                          (V4SI  "wa,v,&?r,?r,?r")
679                                          (V4SF  "wa,v,&?r,?r,?r")
680                                          (V2DI  "wa,v,&?r,?r,?r")
681                                          (V2DF  "wa,v,&?r,?r,?r")
682                                          (V1TI  "wa,v,&?r,?r,?r")])
684 ;; Mode attribute for boolean operation register constraints for operand1
685 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
686                                          (PTI   "r,0,r")
687                                          (V16QI "wa,v,r,0,r")
688                                          (V8HI  "wa,v,r,0,r")
689                                          (V4SI  "wa,v,r,0,r")
690                                          (V4SF  "wa,v,r,0,r")
691                                          (V2DI  "wa,v,r,0,r")
692                                          (V2DF  "wa,v,r,0,r")
693                                          (V1TI  "wa,v,r,0,r")])
695 ;; Mode attribute for boolean operation register constraints for operand2
696 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
697                                          (PTI   "r,r,0")
698                                          (V16QI "wa,v,r,r,0")
699                                          (V8HI  "wa,v,r,r,0")
700                                          (V4SI  "wa,v,r,r,0")
701                                          (V4SF  "wa,v,r,r,0")
702                                          (V2DI  "wa,v,r,r,0")
703                                          (V2DF  "wa,v,r,r,0")
704                                          (V1TI  "wa,v,r,r,0")])
706 ;; Mode attribute for boolean operation register constraints for operand1
707 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
708 ;; is used for operand1 or operand2
709 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
710                                          (PTI   "r,0,0")
711                                          (V16QI "wa,v,r,0,0")
712                                          (V8HI  "wa,v,r,0,0")
713                                          (V4SI  "wa,v,r,0,0")
714                                          (V4SF  "wa,v,r,0,0")
715                                          (V2DI  "wa,v,r,0,0")
716                                          (V2DF  "wa,v,r,0,0")
717                                          (V1TI  "wa,v,r,0,0")])
719 ;; Reload iterator for creating the function to allocate a base register to
720 ;; supplement addressing modes.
721 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
722                               SF SD SI DF DD DI TI PTI KF IF TF])
724 ;; Iterate over smin, smax
725 (define_code_iterator fp_minmax [smin smax])
727 (define_code_attr     minmax    [(smin "min")
728                                  (smax "max")])
730 (define_code_attr     SMINMAX   [(smin "SMIN")
731                                  (smax "SMAX")])
734 ;; Start with fixed-point load and store insns.  Here we put only the more
735 ;; complex forms.  Basic data transfer is done later.
737 (define_insn "zero_extendqi<mode>2"
738   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
739         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
740   ""
741   "@
742    lbz%U1%X1 %0,%1
743    rlwinm %0,%1,0,0xff"
744   [(set_attr "type" "load,shift")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot"
747   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
749                     (const_int 0)))
750    (clobber (match_scratch:EXTQI 0 "=r,r"))]
751   "rs6000_gen_cell_microcode"
752   "@
753    andi. %0,%1,0xff
754    #"
755   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
756   [(set (match_dup 0)
757         (zero_extend:EXTQI (match_dup 1)))
758    (set (match_dup 2)
759         (compare:CC (match_dup 0)
760                     (const_int 0)))]
761   ""
762   [(set_attr "type" "logical")
763    (set_attr "dot" "yes")
764    (set_attr "length" "4,8")])
766 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
767   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
769                     (const_int 0)))
770    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
771         (zero_extend:EXTQI (match_dup 1)))]
772   "rs6000_gen_cell_microcode"
773   "@
774    andi. %0,%1,0xff
775    #"
776   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
777   [(set (match_dup 0)
778         (zero_extend:EXTQI (match_dup 1)))
779    (set (match_dup 2)
780         (compare:CC (match_dup 0)
781                     (const_int 0)))]
782   ""
783   [(set_attr "type" "logical")
784    (set_attr "dot" "yes")
785    (set_attr "length" "4,8")])
788 (define_insn "zero_extendhi<mode>2"
789   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
790         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
791   ""
792   "@
793    lhz%U1%X1 %0,%1
794    rlwinm %0,%1,0,0xffff"
795   [(set_attr "type" "load,shift")])
797 (define_insn_and_split "*zero_extendhi<mode>2_dot"
798   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
800                     (const_int 0)))
801    (clobber (match_scratch:EXTHI 0 "=r,r"))]
802   "rs6000_gen_cell_microcode"
803   "@
804    andi. %0,%1,0xffff
805    #"
806   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
807   [(set (match_dup 0)
808         (zero_extend:EXTHI (match_dup 1)))
809    (set (match_dup 2)
810         (compare:CC (match_dup 0)
811                     (const_int 0)))]
812   ""
813   [(set_attr "type" "logical")
814    (set_attr "dot" "yes")
815    (set_attr "length" "4,8")])
817 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
818   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
819         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
820                     (const_int 0)))
821    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
822         (zero_extend:EXTHI (match_dup 1)))]
823   "rs6000_gen_cell_microcode"
824   "@
825    andi. %0,%1,0xffff
826    #"
827   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
828   [(set (match_dup 0)
829         (zero_extend:EXTHI (match_dup 1)))
830    (set (match_dup 2)
831         (compare:CC (match_dup 0)
832                     (const_int 0)))]
833   ""
834   [(set_attr "type" "logical")
835    (set_attr "dot" "yes")
836    (set_attr "length" "4,8")])
839 (define_insn "zero_extendsi<mode>2"
840   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
841         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
842   ""
843   "@
844    lwz%U1%X1 %0,%1
845    rldicl %0,%1,0,32
846    lfiwzx %0,%y1
847    lxsiwzx %x0,%y1
848    mtvsrwz %x0,%1
849    mfvsrwz %0,%x1
850    xxextractuw %x0,%x1,1"
851   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
853 (define_insn_and_split "*zero_extendsi<mode>2_dot"
854   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
855         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
856                     (const_int 0)))
857    (clobber (match_scratch:EXTSI 0 "=r,r"))]
858   "rs6000_gen_cell_microcode"
859   "@
860    rldicl. %0,%1,0,32
861    #"
862   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
863   [(set (match_dup 0)
864         (zero_extend:DI (match_dup 1)))
865    (set (match_dup 2)
866         (compare:CC (match_dup 0)
867                     (const_int 0)))]
868   ""
869   [(set_attr "type" "shift")
870    (set_attr "dot" "yes")
871    (set_attr "length" "4,8")])
873 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
874   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
875         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
876                     (const_int 0)))
877    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
878         (zero_extend:EXTSI (match_dup 1)))]
879   "rs6000_gen_cell_microcode"
880   "@
881    rldicl. %0,%1,0,32
882    #"
883   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
884   [(set (match_dup 0)
885         (zero_extend:EXTSI (match_dup 1)))
886    (set (match_dup 2)
887         (compare:CC (match_dup 0)
888                     (const_int 0)))]
889   ""
890   [(set_attr "type" "shift")
891    (set_attr "dot" "yes")
892    (set_attr "length" "4,8")])
895 (define_insn "extendqi<mode>2"
896   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
897         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
898   ""
899   "extsb %0,%1"
900   [(set_attr "type" "exts")])
902 (define_insn_and_split "*extendqi<mode>2_dot"
903   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
904         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
905                     (const_int 0)))
906    (clobber (match_scratch:EXTQI 0 "=r,r"))]
907   "rs6000_gen_cell_microcode"
908   "@
909    extsb. %0,%1
910    #"
911   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
912   [(set (match_dup 0)
913         (sign_extend:EXTQI (match_dup 1)))
914    (set (match_dup 2)
915         (compare:CC (match_dup 0)
916                     (const_int 0)))]
917   ""
918   [(set_attr "type" "exts")
919    (set_attr "dot" "yes")
920    (set_attr "length" "4,8")])
922 (define_insn_and_split "*extendqi<mode>2_dot2"
923   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
924         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
925                     (const_int 0)))
926    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
927         (sign_extend:EXTQI (match_dup 1)))]
928   "rs6000_gen_cell_microcode"
929   "@
930    extsb. %0,%1
931    #"
932   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
933   [(set (match_dup 0)
934         (sign_extend:EXTQI (match_dup 1)))
935    (set (match_dup 2)
936         (compare:CC (match_dup 0)
937                     (const_int 0)))]
938   ""
939   [(set_attr "type" "exts")
940    (set_attr "dot" "yes")
941    (set_attr "length" "4,8")])
944 (define_expand "extendhi<mode>2"
945   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
946         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
947   ""
948   "")
950 (define_insn "*extendhi<mode>2"
951   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
952         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
953   "rs6000_gen_cell_microcode"
954   "@
955    lha%U1%X1 %0,%1
956    extsh %0,%1"
957   [(set_attr "type" "load,exts")
958    (set_attr "sign_extend" "yes")])
960 (define_insn "*extendhi<mode>2_noload"
961   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
962         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
963   "!rs6000_gen_cell_microcode"
964   "extsh %0,%1"
965   [(set_attr "type" "exts")])
967 (define_insn_and_split "*extendhi<mode>2_dot"
968   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
969         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
970                     (const_int 0)))
971    (clobber (match_scratch:EXTHI 0 "=r,r"))]
972   "rs6000_gen_cell_microcode"
973   "@
974    extsh. %0,%1
975    #"
976   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
977   [(set (match_dup 0)
978         (sign_extend:EXTHI (match_dup 1)))
979    (set (match_dup 2)
980         (compare:CC (match_dup 0)
981                     (const_int 0)))]
982   ""
983   [(set_attr "type" "exts")
984    (set_attr "dot" "yes")
985    (set_attr "length" "4,8")])
987 (define_insn_and_split "*extendhi<mode>2_dot2"
988   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
989         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
990                     (const_int 0)))
991    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
992         (sign_extend:EXTHI (match_dup 1)))]
993   "rs6000_gen_cell_microcode"
994   "@
995    extsh. %0,%1
996    #"
997   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
998   [(set (match_dup 0)
999         (sign_extend:EXTHI (match_dup 1)))
1000    (set (match_dup 2)
1001         (compare:CC (match_dup 0)
1002                     (const_int 0)))]
1003   ""
1004   [(set_attr "type" "exts")
1005    (set_attr "dot" "yes")
1006    (set_attr "length" "4,8")])
1009 (define_insn "extendsi<mode>2"
1010   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1011         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1012   ""
1013   "@
1014    lwa%U1%X1 %0,%1
1015    extsw %0,%1
1016    lfiwax %0,%y1
1017    lxsiwax %x0,%y1
1018    mtvsrwa %x0,%1
1019    vextsw2d %0,%1"
1020   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1021    (set_attr "sign_extend" "yes")])
1023 (define_insn_and_split "*extendsi<mode>2_dot"
1024   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1025         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1026                     (const_int 0)))
1027    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1028   "rs6000_gen_cell_microcode"
1029   "@
1030    extsw. %0,%1
1031    #"
1032   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1033   [(set (match_dup 0)
1034         (sign_extend:EXTSI (match_dup 1)))
1035    (set (match_dup 2)
1036         (compare:CC (match_dup 0)
1037                     (const_int 0)))]
1038   ""
1039   [(set_attr "type" "exts")
1040    (set_attr "dot" "yes")
1041    (set_attr "length" "4,8")])
1043 (define_insn_and_split "*extendsi<mode>2_dot2"
1044   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1045         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1046                     (const_int 0)))
1047    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1048         (sign_extend:EXTSI (match_dup 1)))]
1049   "rs6000_gen_cell_microcode"
1050   "@
1051    extsw. %0,%1
1052    #"
1053   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1054   [(set (match_dup 0)
1055         (sign_extend:EXTSI (match_dup 1)))
1056    (set (match_dup 2)
1057         (compare:CC (match_dup 0)
1058                     (const_int 0)))]
1059   ""
1060   [(set_attr "type" "exts")
1061    (set_attr "dot" "yes")
1062    (set_attr "length" "4,8")])
1064 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1066 (define_insn "*macchwc"
1067   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1068         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1069                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1070                                        (const_int 16))
1071                                       (sign_extend:SI
1072                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1073                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1074                     (const_int 0)))
1075    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1076         (plus:SI (mult:SI (ashiftrt:SI
1077                            (match_dup 2)
1078                            (const_int 16))
1079                           (sign_extend:SI
1080                            (match_dup 1)))
1081                  (match_dup 4)))]
1082   "TARGET_MULHW"
1083   "macchw. %0,%1,%2"
1084   [(set_attr "type" "halfmul")])
1086 (define_insn "*macchw"
1087   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1088         (plus:SI (mult:SI (ashiftrt:SI
1089                            (match_operand:SI 2 "gpc_reg_operand" "r")
1090                            (const_int 16))
1091                           (sign_extend:SI
1092                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1093                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1094   "TARGET_MULHW"
1095   "macchw %0,%1,%2"
1096   [(set_attr "type" "halfmul")])
1098 (define_insn "*macchwuc"
1099   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1100         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1101                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1102                                        (const_int 16))
1103                                       (zero_extend:SI
1104                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1105                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1106                     (const_int 0)))
1107    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1108         (plus:SI (mult:SI (lshiftrt:SI
1109                            (match_dup 2)
1110                            (const_int 16))
1111                           (zero_extend:SI
1112                            (match_dup 1)))
1113                  (match_dup 4)))]
1114   "TARGET_MULHW"
1115   "macchwu. %0,%1,%2"
1116   [(set_attr "type" "halfmul")])
1118 (define_insn "*macchwu"
1119   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1120         (plus:SI (mult:SI (lshiftrt:SI
1121                            (match_operand:SI 2 "gpc_reg_operand" "r")
1122                            (const_int 16))
1123                           (zero_extend:SI
1124                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1125                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1126   "TARGET_MULHW"
1127   "macchwu %0,%1,%2"
1128   [(set_attr "type" "halfmul")])
1130 (define_insn "*machhwc"
1131   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1132         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1133                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1134                                        (const_int 16))
1135                                       (ashiftrt:SI
1136                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1137                                        (const_int 16)))
1138                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1139                     (const_int 0)))
1140    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1141         (plus:SI (mult:SI (ashiftrt:SI
1142                            (match_dup 1)
1143                            (const_int 16))
1144                           (ashiftrt:SI
1145                            (match_dup 2)
1146                            (const_int 16)))
1147                  (match_dup 4)))]
1148   "TARGET_MULHW"
1149   "machhw. %0,%1,%2"
1150   [(set_attr "type" "halfmul")])
1152 (define_insn "*machhw"
1153   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154         (plus:SI (mult:SI (ashiftrt:SI
1155                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1156                            (const_int 16))
1157                           (ashiftrt:SI
1158                            (match_operand:SI 2 "gpc_reg_operand" "r")
1159                            (const_int 16)))
1160                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1161   "TARGET_MULHW"
1162   "machhw %0,%1,%2"
1163   [(set_attr "type" "halfmul")])
1165 (define_insn "*machhwuc"
1166   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1167         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1168                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1169                                        (const_int 16))
1170                                       (lshiftrt:SI
1171                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1172                                        (const_int 16)))
1173                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1174                     (const_int 0)))
1175    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1176         (plus:SI (mult:SI (lshiftrt:SI
1177                            (match_dup 1)
1178                            (const_int 16))
1179                           (lshiftrt:SI
1180                            (match_dup 2)
1181                            (const_int 16)))
1182                  (match_dup 4)))]
1183   "TARGET_MULHW"
1184   "machhwu. %0,%1,%2"
1185   [(set_attr "type" "halfmul")])
1187 (define_insn "*machhwu"
1188   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1189         (plus:SI (mult:SI (lshiftrt:SI
1190                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1191                            (const_int 16))
1192                           (lshiftrt:SI
1193                            (match_operand:SI 2 "gpc_reg_operand" "r")
1194                            (const_int 16)))
1195                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1196   "TARGET_MULHW"
1197   "machhwu %0,%1,%2"
1198   [(set_attr "type" "halfmul")])
1200 (define_insn "*maclhwc"
1201   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1202         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1203                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1204                                       (sign_extend:SI
1205                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1206                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1207                     (const_int 0)))
1208    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1209         (plus:SI (mult:SI (sign_extend:SI
1210                            (match_dup 1))
1211                           (sign_extend:SI
1212                            (match_dup 2)))
1213                  (match_dup 4)))]
1214   "TARGET_MULHW"
1215   "maclhw. %0,%1,%2"
1216   [(set_attr "type" "halfmul")])
1218 (define_insn "*maclhw"
1219   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1220         (plus:SI (mult:SI (sign_extend:SI
1221                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1222                           (sign_extend:SI
1223                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1224                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1225   "TARGET_MULHW"
1226   "maclhw %0,%1,%2"
1227   [(set_attr "type" "halfmul")])
1229 (define_insn "*maclhwuc"
1230   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1231         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1232                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1233                                       (zero_extend:SI
1234                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1235                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1236                     (const_int 0)))
1237    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1238         (plus:SI (mult:SI (zero_extend:SI
1239                            (match_dup 1))
1240                           (zero_extend:SI
1241                            (match_dup 2)))
1242                  (match_dup 4)))]
1243   "TARGET_MULHW"
1244   "maclhwu. %0,%1,%2"
1245   [(set_attr "type" "halfmul")])
1247 (define_insn "*maclhwu"
1248   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1249         (plus:SI (mult:SI (zero_extend:SI
1250                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1251                           (zero_extend:SI
1252                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1253                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1254   "TARGET_MULHW"
1255   "maclhwu %0,%1,%2"
1256   [(set_attr "type" "halfmul")])
1258 (define_insn "*nmacchwc"
1259   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1260         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1261                               (mult:SI (ashiftrt:SI
1262                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1263                                         (const_int 16))
1264                                        (sign_extend:SI
1265                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1266                     (const_int 0)))
1267    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1268         (minus:SI (match_dup 4)
1269                   (mult:SI (ashiftrt:SI
1270                             (match_dup 2)
1271                             (const_int 16))
1272                            (sign_extend:SI
1273                             (match_dup 1)))))]
1274   "TARGET_MULHW"
1275   "nmacchw. %0,%1,%2"
1276   [(set_attr "type" "halfmul")])
1278 (define_insn "*nmacchw"
1279   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1280         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1281                   (mult:SI (ashiftrt:SI
1282                             (match_operand:SI 2 "gpc_reg_operand" "r")
1283                             (const_int 16))
1284                            (sign_extend:SI
1285                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1286   "TARGET_MULHW"
1287   "nmacchw %0,%1,%2"
1288   [(set_attr "type" "halfmul")])
1290 (define_insn "*nmachhwc"
1291   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1293                               (mult:SI (ashiftrt:SI
1294                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1295                                         (const_int 16))
1296                                        (ashiftrt:SI
1297                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1298                                         (const_int 16))))
1299                     (const_int 0)))
1300    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1301         (minus:SI (match_dup 4)
1302                   (mult:SI (ashiftrt:SI
1303                             (match_dup 1)
1304                             (const_int 16))
1305                            (ashiftrt:SI
1306                             (match_dup 2)
1307                             (const_int 16)))))]
1308   "TARGET_MULHW"
1309   "nmachhw. %0,%1,%2"
1310   [(set_attr "type" "halfmul")])
1312 (define_insn "*nmachhw"
1313   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1314         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1315                   (mult:SI (ashiftrt:SI
1316                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1317                             (const_int 16))
1318                            (ashiftrt:SI
1319                             (match_operand:SI 2 "gpc_reg_operand" "r")
1320                             (const_int 16)))))]
1321   "TARGET_MULHW"
1322   "nmachhw %0,%1,%2"
1323   [(set_attr "type" "halfmul")])
1325 (define_insn "*nmaclhwc"
1326   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1327         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1328                               (mult:SI (sign_extend:SI
1329                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1330                                        (sign_extend:SI
1331                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1332                     (const_int 0)))
1333    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1334         (minus:SI (match_dup 4)
1335                   (mult:SI (sign_extend:SI
1336                             (match_dup 1))
1337                            (sign_extend:SI
1338                             (match_dup 2)))))]
1339   "TARGET_MULHW"
1340   "nmaclhw. %0,%1,%2"
1341   [(set_attr "type" "halfmul")])
1343 (define_insn "*nmaclhw"
1344   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1345         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1346                   (mult:SI (sign_extend:SI
1347                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1348                            (sign_extend:SI
1349                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1350   "TARGET_MULHW"
1351   "nmaclhw %0,%1,%2"
1352   [(set_attr "type" "halfmul")])
1354 (define_insn "*mulchwc"
1355   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1356         (compare:CC (mult:SI (ashiftrt:SI
1357                               (match_operand:SI 2 "gpc_reg_operand" "r")
1358                               (const_int 16))
1359                              (sign_extend:SI
1360                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1361                     (const_int 0)))
1362    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1363         (mult:SI (ashiftrt:SI
1364                   (match_dup 2)
1365                   (const_int 16))
1366                  (sign_extend:SI
1367                   (match_dup 1))))]
1368   "TARGET_MULHW"
1369   "mulchw. %0,%1,%2"
1370   [(set_attr "type" "halfmul")])
1372 (define_insn "*mulchw"
1373   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1374         (mult:SI (ashiftrt:SI
1375                   (match_operand:SI 2 "gpc_reg_operand" "r")
1376                   (const_int 16))
1377                  (sign_extend:SI
1378                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1379   "TARGET_MULHW"
1380   "mulchw %0,%1,%2"
1381   [(set_attr "type" "halfmul")])
1383 (define_insn "*mulchwuc"
1384   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1385         (compare:CC (mult:SI (lshiftrt:SI
1386                               (match_operand:SI 2 "gpc_reg_operand" "r")
1387                               (const_int 16))
1388                              (zero_extend:SI
1389                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1390                     (const_int 0)))
1391    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1392         (mult:SI (lshiftrt:SI
1393                   (match_dup 2)
1394                   (const_int 16))
1395                  (zero_extend:SI
1396                   (match_dup 1))))]
1397   "TARGET_MULHW"
1398   "mulchwu. %0,%1,%2"
1399   [(set_attr "type" "halfmul")])
1401 (define_insn "*mulchwu"
1402   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1403         (mult:SI (lshiftrt:SI
1404                   (match_operand:SI 2 "gpc_reg_operand" "r")
1405                   (const_int 16))
1406                  (zero_extend:SI
1407                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1408   "TARGET_MULHW"
1409   "mulchwu %0,%1,%2"
1410   [(set_attr "type" "halfmul")])
1412 (define_insn "*mulhhwc"
1413   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1414         (compare:CC (mult:SI (ashiftrt:SI
1415                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1416                               (const_int 16))
1417                              (ashiftrt:SI
1418                               (match_operand:SI 2 "gpc_reg_operand" "r")
1419                               (const_int 16)))
1420                     (const_int 0)))
1421    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1422         (mult:SI (ashiftrt:SI
1423                   (match_dup 1)
1424                   (const_int 16))
1425                  (ashiftrt:SI
1426                   (match_dup 2)
1427                   (const_int 16))))]
1428   "TARGET_MULHW"
1429   "mulhhw. %0,%1,%2"
1430   [(set_attr "type" "halfmul")])
1432 (define_insn "*mulhhw"
1433   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1434         (mult:SI (ashiftrt:SI
1435                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1436                   (const_int 16))
1437                  (ashiftrt:SI
1438                   (match_operand:SI 2 "gpc_reg_operand" "r")
1439                   (const_int 16))))]
1440   "TARGET_MULHW"
1441   "mulhhw %0,%1,%2"
1442   [(set_attr "type" "halfmul")])
1444 (define_insn "*mulhhwuc"
1445   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1446         (compare:CC (mult:SI (lshiftrt:SI
1447                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1448                               (const_int 16))
1449                              (lshiftrt:SI
1450                               (match_operand:SI 2 "gpc_reg_operand" "r")
1451                               (const_int 16)))
1452                     (const_int 0)))
1453    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454         (mult:SI (lshiftrt:SI
1455                   (match_dup 1)
1456                   (const_int 16))
1457                  (lshiftrt:SI
1458                   (match_dup 2)
1459                   (const_int 16))))]
1460   "TARGET_MULHW"
1461   "mulhhwu. %0,%1,%2"
1462   [(set_attr "type" "halfmul")])
1464 (define_insn "*mulhhwu"
1465   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1466         (mult:SI (lshiftrt:SI
1467                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1468                   (const_int 16))
1469                  (lshiftrt:SI
1470                   (match_operand:SI 2 "gpc_reg_operand" "r")
1471                   (const_int 16))))]
1472   "TARGET_MULHW"
1473   "mulhhwu %0,%1,%2"
1474   [(set_attr "type" "halfmul")])
1476 (define_insn "*mullhwc"
1477   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1478         (compare:CC (mult:SI (sign_extend:SI
1479                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1480                              (sign_extend:SI
1481                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1482                     (const_int 0)))
1483    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484         (mult:SI (sign_extend:SI
1485                   (match_dup 1))
1486                  (sign_extend:SI
1487                   (match_dup 2))))]
1488   "TARGET_MULHW"
1489   "mullhw. %0,%1,%2"
1490   [(set_attr "type" "halfmul")])
1492 (define_insn "*mullhw"
1493   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1494         (mult:SI (sign_extend:SI
1495                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1496                  (sign_extend:SI
1497                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1498   "TARGET_MULHW"
1499   "mullhw %0,%1,%2"
1500   [(set_attr "type" "halfmul")])
1502 (define_insn "*mullhwuc"
1503   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1504         (compare:CC (mult:SI (zero_extend:SI
1505                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1506                              (zero_extend:SI
1507                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1508                     (const_int 0)))
1509    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510         (mult:SI (zero_extend:SI
1511                   (match_dup 1))
1512                  (zero_extend:SI
1513                   (match_dup 2))))]
1514   "TARGET_MULHW"
1515   "mullhwu. %0,%1,%2"
1516   [(set_attr "type" "halfmul")])
1518 (define_insn "*mullhwu"
1519   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1520         (mult:SI (zero_extend:SI
1521                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1522                  (zero_extend:SI
1523                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1524   "TARGET_MULHW"
1525   "mullhwu %0,%1,%2"
1526   [(set_attr "type" "halfmul")])
1528 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1529 (define_insn "dlmzb"
1530   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1531         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1532                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1533                    UNSPEC_DLMZB_CR))
1534    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1535         (unspec:SI [(match_dup 1)
1536                     (match_dup 2)]
1537                    UNSPEC_DLMZB))]
1538   "TARGET_DLMZB"
1539   "dlmzb. %0,%1,%2")
1541 (define_expand "strlensi"
1542   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1543         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1544                     (match_operand:QI 2 "const_int_operand" "")
1545                     (match_operand 3 "const_int_operand" "")]
1546                    UNSPEC_DLMZB_STRLEN))
1547    (clobber (match_scratch:CC 4 "=x"))]
1548   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1550   rtx result = operands[0];
1551   rtx src = operands[1];
1552   rtx search_char = operands[2];
1553   rtx align = operands[3];
1554   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1555   rtx loop_label, end_label, mem, cr0, cond;
1556   if (search_char != const0_rtx
1557       || GET_CODE (align) != CONST_INT
1558       || INTVAL (align) < 8)
1559         FAIL;
1560   word1 = gen_reg_rtx (SImode);
1561   word2 = gen_reg_rtx (SImode);
1562   scratch_dlmzb = gen_reg_rtx (SImode);
1563   scratch_string = gen_reg_rtx (Pmode);
1564   loop_label = gen_label_rtx ();
1565   end_label = gen_label_rtx ();
1566   addr = force_reg (Pmode, XEXP (src, 0));
1567   emit_move_insn (scratch_string, addr);
1568   emit_label (loop_label);
1569   mem = change_address (src, SImode, scratch_string);
1570   emit_move_insn (word1, mem);
1571   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1572   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1573   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1574   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1575   emit_jump_insn (gen_rtx_SET (pc_rtx,
1576                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1577                                                      cond,
1578                                                      gen_rtx_LABEL_REF
1579                                                        (VOIDmode,
1580                                                         end_label),
1581                                                      pc_rtx)));
1582   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1583   emit_jump_insn (gen_rtx_SET (pc_rtx,
1584                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1585   emit_barrier ();
1586   emit_label (end_label);
1587   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1588   emit_insn (gen_subsi3 (result, scratch_string, addr));
1589   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1590   DONE;
1593 ;; Fixed-point arithmetic insns.
1595 (define_expand "add<mode>3"
1596   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1597         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1598                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1599   ""
1601   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1602     {
1603       rtx lo0 = gen_lowpart (SImode, operands[0]);
1604       rtx lo1 = gen_lowpart (SImode, operands[1]);
1605       rtx lo2 = gen_lowpart (SImode, operands[2]);
1606       rtx hi0 = gen_highpart (SImode, operands[0]);
1607       rtx hi1 = gen_highpart (SImode, operands[1]);
1608       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1610       if (!reg_or_short_operand (lo2, SImode))
1611         lo2 = force_reg (SImode, lo2);
1612       if (!adde_operand (hi2, SImode))
1613         hi2 = force_reg (SImode, hi2);
1615       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1616       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1617       DONE;
1618     }
1620   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1621     {
1622       rtx tmp = ((!can_create_pseudo_p ()
1623                   || rtx_equal_p (operands[0], operands[1]))
1624                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1626       HOST_WIDE_INT val = INTVAL (operands[2]);
1627       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1628       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1630       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1631         FAIL;
1633       /* The ordering here is important for the prolog expander.
1634          When space is allocated from the stack, adding 'low' first may
1635          produce a temporary deallocation (which would be bad).  */
1636       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1637       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1638       DONE;
1639     }
1642 (define_insn "*add<mode>3"
1643   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1644         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1645                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1646   ""
1647   "@
1648    add %0,%1,%2
1649    addi %0,%1,%2
1650    addis %0,%1,%v2"
1651   [(set_attr "type" "add")])
1653 (define_insn "addsi3_high"
1654   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1655         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1656                  (high:SI (match_operand 2 "" ""))))]
1657   "TARGET_MACHO && !TARGET_64BIT"
1658   "addis %0,%1,ha16(%2)"
1659   [(set_attr "type" "add")])
1661 (define_insn_and_split "*add<mode>3_dot"
1662   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1663         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1664                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1665                     (const_int 0)))
1666    (clobber (match_scratch:GPR 0 "=r,r"))]
1667   "<MODE>mode == Pmode"
1668   "@
1669    add. %0,%1,%2
1670    #"
1671   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1672   [(set (match_dup 0)
1673         (plus:GPR (match_dup 1)
1674                  (match_dup 2)))
1675    (set (match_dup 3)
1676         (compare:CC (match_dup 0)
1677                     (const_int 0)))]
1678   ""
1679   [(set_attr "type" "add")
1680    (set_attr "dot" "yes")
1681    (set_attr "length" "4,8")])
1683 (define_insn_and_split "*add<mode>3_dot2"
1684   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1685         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1686                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1687                     (const_int 0)))
1688    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1689         (plus:GPR (match_dup 1)
1690                   (match_dup 2)))]
1691   "<MODE>mode == Pmode"
1692   "@
1693    add. %0,%1,%2
1694    #"
1695   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1696   [(set (match_dup 0)
1697         (plus:GPR (match_dup 1)
1698                   (match_dup 2)))
1699    (set (match_dup 3)
1700         (compare:CC (match_dup 0)
1701                     (const_int 0)))]
1702   ""
1703   [(set_attr "type" "add")
1704    (set_attr "dot" "yes")
1705    (set_attr "length" "4,8")])
1707 (define_insn_and_split "*add<mode>3_imm_dot"
1708   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1709         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1710                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1711                     (const_int 0)))
1712    (clobber (match_scratch:GPR 0 "=r,r"))
1713    (clobber (reg:GPR CA_REGNO))]
1714   "<MODE>mode == Pmode"
1715   "@
1716    addic. %0,%1,%2
1717    #"
1718   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1719   [(set (match_dup 0)
1720         (plus:GPR (match_dup 1)
1721                   (match_dup 2)))
1722    (set (match_dup 3)
1723         (compare:CC (match_dup 0)
1724                     (const_int 0)))]
1725   ""
1726   [(set_attr "type" "add")
1727    (set_attr "dot" "yes")
1728    (set_attr "length" "4,8")])
1730 (define_insn_and_split "*add<mode>3_imm_dot2"
1731   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1732         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1733                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1734                     (const_int 0)))
1735    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1736         (plus:GPR (match_dup 1)
1737                   (match_dup 2)))
1738    (clobber (reg:GPR CA_REGNO))]
1739   "<MODE>mode == Pmode"
1740   "@
1741    addic. %0,%1,%2
1742    #"
1743   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1744   [(set (match_dup 0)
1745         (plus:GPR (match_dup 1)
1746                   (match_dup 2)))
1747    (set (match_dup 3)
1748         (compare:CC (match_dup 0)
1749                     (const_int 0)))]
1750   ""
1751   [(set_attr "type" "add")
1752    (set_attr "dot" "yes")
1753    (set_attr "length" "4,8")])
1755 ;; Split an add that we can't do in one insn into two insns, each of which
1756 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1757 ;; add should be last in case the result gets used in an address.
1759 (define_split
1760   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1761         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1762                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1763   ""
1764   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1765    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1767   HOST_WIDE_INT val = INTVAL (operands[2]);
1768   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1769   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1771   operands[4] = GEN_INT (low);
1772   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1773     operands[3] = GEN_INT (rest);
1774   else if (can_create_pseudo_p ())
1775     {
1776       operands[3] = gen_reg_rtx (DImode);
1777       emit_move_insn (operands[3], operands[2]);
1778       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1779       DONE;
1780     }
1781   else
1782     FAIL;
1786 (define_insn "add<mode>3_carry"
1787   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1788         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1789                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1790    (set (reg:P CA_REGNO)
1791         (ltu:P (plus:P (match_dup 1)
1792                        (match_dup 2))
1793                (match_dup 1)))]
1794   ""
1795   "add%I2c %0,%1,%2"
1796   [(set_attr "type" "add")])
1798 (define_insn "*add<mode>3_imm_carry_pos"
1799   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1800         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1801                 (match_operand:P 2 "short_cint_operand" "n")))
1802    (set (reg:P CA_REGNO)
1803         (geu:P (match_dup 1)
1804                (match_operand:P 3 "const_int_operand" "n")))]
1805   "INTVAL (operands[2]) > 0
1806    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1807   "addic %0,%1,%2"
1808   [(set_attr "type" "add")])
1810 (define_insn "*add<mode>3_imm_carry_0"
1811   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1812         (match_operand:P 1 "gpc_reg_operand" "r"))
1813    (set (reg:P CA_REGNO)
1814         (const_int 0))]
1815   ""
1816   "addic %0,%1,0"
1817   [(set_attr "type" "add")])
1819 (define_insn "*add<mode>3_imm_carry_m1"
1820   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1821         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1822                 (const_int -1)))
1823    (set (reg:P CA_REGNO)
1824         (ne:P (match_dup 1)
1825               (const_int 0)))]
1826   ""
1827   "addic %0,%1,-1"
1828   [(set_attr "type" "add")])
1830 (define_insn "*add<mode>3_imm_carry_neg"
1831   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1832         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1833                 (match_operand:P 2 "short_cint_operand" "n")))
1834    (set (reg:P CA_REGNO)
1835         (gtu:P (match_dup 1)
1836                (match_operand:P 3 "const_int_operand" "n")))]
1837   "INTVAL (operands[2]) < 0
1838    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1839   "addic %0,%1,%2"
1840   [(set_attr "type" "add")])
1843 (define_expand "add<mode>3_carry_in"
1844   [(parallel [
1845      (set (match_operand:GPR 0 "gpc_reg_operand")
1846           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1847                               (match_operand:GPR 2 "adde_operand"))
1848                     (reg:GPR CA_REGNO)))
1849      (clobber (reg:GPR CA_REGNO))])]
1850   ""
1852   if (operands[2] == const0_rtx)
1853     {
1854       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1855       DONE;
1856     }
1857   if (operands[2] == constm1_rtx)
1858     {
1859       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1860       DONE;
1861     }
1864 (define_insn "*add<mode>3_carry_in_internal"
1865   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1866         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1867                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1868                   (reg:GPR CA_REGNO)))
1869    (clobber (reg:GPR CA_REGNO))]
1870   ""
1871   "adde %0,%1,%2"
1872   [(set_attr "type" "add")])
1874 (define_insn "add<mode>3_carry_in_0"
1875   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1876         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1877                   (reg:GPR CA_REGNO)))
1878    (clobber (reg:GPR CA_REGNO))]
1879   ""
1880   "addze %0,%1"
1881   [(set_attr "type" "add")])
1883 (define_insn "add<mode>3_carry_in_m1"
1884   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1885         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1886                             (reg:GPR CA_REGNO))
1887                   (const_int -1)))
1888    (clobber (reg:GPR CA_REGNO))]
1889   ""
1890   "addme %0,%1"
1891   [(set_attr "type" "add")])
1894 (define_expand "one_cmpl<mode>2"
1895   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1896         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1897   ""
1899   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1900     {
1901       rs6000_split_logical (operands, NOT, false, false, false);
1902       DONE;
1903     }
1906 (define_insn "*one_cmpl<mode>2"
1907   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1908         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1909   ""
1910   "not %0,%1")
1912 (define_insn_and_split "*one_cmpl<mode>2_dot"
1913   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1914         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1915                     (const_int 0)))
1916    (clobber (match_scratch:GPR 0 "=r,r"))]
1917   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1918   "@
1919    not. %0,%1
1920    #"
1921   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1922   [(set (match_dup 0)
1923         (not:GPR (match_dup 1)))
1924    (set (match_dup 2)
1925         (compare:CC (match_dup 0)
1926                     (const_int 0)))]
1927   ""
1928   [(set_attr "type" "logical")
1929    (set_attr "dot" "yes")
1930    (set_attr "length" "4,8")])
1932 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1933   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1934         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1935                     (const_int 0)))
1936    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1937         (not:GPR (match_dup 1)))]
1938   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1939   "@
1940    not. %0,%1
1941    #"
1942   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1943   [(set (match_dup 0)
1944         (not:GPR (match_dup 1)))
1945    (set (match_dup 2)
1946         (compare:CC (match_dup 0)
1947                     (const_int 0)))]
1948   ""
1949   [(set_attr "type" "logical")
1950    (set_attr "dot" "yes")
1951    (set_attr "length" "4,8")])
1954 (define_expand "sub<mode>3"
1955   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1956         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1957                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1958   ""
1960   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1961     {
1962       rtx lo0 = gen_lowpart (SImode, operands[0]);
1963       rtx lo1 = gen_lowpart (SImode, operands[1]);
1964       rtx lo2 = gen_lowpart (SImode, operands[2]);
1965       rtx hi0 = gen_highpart (SImode, operands[0]);
1966       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1967       rtx hi2 = gen_highpart (SImode, operands[2]);
1969       if (!reg_or_short_operand (lo1, SImode))
1970         lo1 = force_reg (SImode, lo1);
1971       if (!adde_operand (hi1, SImode))
1972         hi1 = force_reg (SImode, hi1);
1974       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1975       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1976       DONE;
1977     }
1979   if (short_cint_operand (operands[1], <MODE>mode))
1980     {
1981       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1982       DONE;
1983     }
1986 (define_insn "*subf<mode>3"
1987   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1988         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1989                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1990   ""
1991   "subf %0,%1,%2"
1992   [(set_attr "type" "add")])
1994 (define_insn_and_split "*subf<mode>3_dot"
1995   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1996         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1997                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1998                     (const_int 0)))
1999    (clobber (match_scratch:GPR 0 "=r,r"))]
2000   "<MODE>mode == Pmode"
2001   "@
2002    subf. %0,%1,%2
2003    #"
2004   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2005   [(set (match_dup 0)
2006         (minus:GPR (match_dup 2)
2007                    (match_dup 1)))
2008    (set (match_dup 3)
2009         (compare:CC (match_dup 0)
2010                     (const_int 0)))]
2011   ""
2012   [(set_attr "type" "add")
2013    (set_attr "dot" "yes")
2014    (set_attr "length" "4,8")])
2016 (define_insn_and_split "*subf<mode>3_dot2"
2017   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2018         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2019                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2020                     (const_int 0)))
2021    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2022         (minus:GPR (match_dup 2)
2023                    (match_dup 1)))]
2024   "<MODE>mode == Pmode"
2025   "@
2026    subf. %0,%1,%2
2027    #"
2028   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2029   [(set (match_dup 0)
2030         (minus:GPR (match_dup 2)
2031                    (match_dup 1)))
2032    (set (match_dup 3)
2033         (compare:CC (match_dup 0)
2034                     (const_int 0)))]
2035   ""
2036   [(set_attr "type" "add")
2037    (set_attr "dot" "yes")
2038    (set_attr "length" "4,8")])
2040 (define_insn "subf<mode>3_imm"
2041   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2042         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2043                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2044    (clobber (reg:GPR CA_REGNO))]
2045   ""
2046   "subfic %0,%1,%2"
2047   [(set_attr "type" "add")])
2050 (define_insn "subf<mode>3_carry"
2051   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2052         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2053                  (match_operand:P 1 "gpc_reg_operand" "r")))
2054    (set (reg:P CA_REGNO)
2055         (leu:P (match_dup 1)
2056                (match_dup 2)))]
2057   ""
2058   "subf%I2c %0,%1,%2"
2059   [(set_attr "type" "add")])
2061 (define_insn "*subf<mode>3_imm_carry_0"
2062   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2063         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2064    (set (reg:P CA_REGNO)
2065         (eq:P (match_dup 1)
2066               (const_int 0)))]
2067   ""
2068   "subfic %0,%1,0"
2069   [(set_attr "type" "add")])
2071 (define_insn "*subf<mode>3_imm_carry_m1"
2072   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2073         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2074    (set (reg:P CA_REGNO)
2075         (const_int 1))]
2076   ""
2077   "subfic %0,%1,-1"
2078   [(set_attr "type" "add")])
2081 (define_expand "subf<mode>3_carry_in"
2082   [(parallel [
2083      (set (match_operand:GPR 0 "gpc_reg_operand")
2084           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2085                               (reg:GPR CA_REGNO))
2086                     (match_operand:GPR 2 "adde_operand")))
2087      (clobber (reg:GPR CA_REGNO))])]
2088   ""
2090   if (operands[2] == const0_rtx)
2091     {
2092       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2093       DONE;
2094     }
2095   if (operands[2] == constm1_rtx)
2096     {
2097       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2098       DONE;
2099     }
2102 (define_insn "*subf<mode>3_carry_in_internal"
2103   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2104         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2105                             (reg:GPR CA_REGNO))
2106                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2107    (clobber (reg:GPR CA_REGNO))]
2108   ""
2109   "subfe %0,%1,%2"
2110   [(set_attr "type" "add")])
2112 (define_insn "subf<mode>3_carry_in_0"
2113   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2114         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2115                   (reg:GPR CA_REGNO)))
2116    (clobber (reg:GPR CA_REGNO))]
2117   ""
2118   "subfze %0,%1"
2119   [(set_attr "type" "add")])
2121 (define_insn "subf<mode>3_carry_in_m1"
2122   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2123         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2124                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2125                   (const_int -2)))
2126    (clobber (reg:GPR CA_REGNO))]
2127   ""
2128   "subfme %0,%1"
2129   [(set_attr "type" "add")])
2131 (define_insn "subf<mode>3_carry_in_xx"
2132   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2133         (plus:GPR (reg:GPR CA_REGNO)
2134                   (const_int -1)))
2135    (clobber (reg:GPR CA_REGNO))]
2136   ""
2137   "subfe %0,%0,%0"
2138   [(set_attr "type" "add")])
2141 (define_insn "neg<mode>2"
2142   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2143         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2144   ""
2145   "neg %0,%1"
2146   [(set_attr "type" "add")])
2148 (define_insn_and_split "*neg<mode>2_dot"
2149   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2150         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2151                     (const_int 0)))
2152    (clobber (match_scratch:GPR 0 "=r,r"))]
2153   "<MODE>mode == Pmode"
2154   "@
2155    neg. %0,%1
2156    #"
2157   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2158   [(set (match_dup 0)
2159         (neg:GPR (match_dup 1)))
2160    (set (match_dup 2)
2161         (compare:CC (match_dup 0)
2162                     (const_int 0)))]
2163   ""
2164   [(set_attr "type" "add")
2165    (set_attr "dot" "yes")
2166    (set_attr "length" "4,8")])
2168 (define_insn_and_split "*neg<mode>2_dot2"
2169   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2170         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2171                     (const_int 0)))
2172    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2173         (neg:GPR (match_dup 1)))]
2174   "<MODE>mode == Pmode"
2175   "@
2176    neg. %0,%1
2177    #"
2178   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2179   [(set (match_dup 0)
2180         (neg:GPR (match_dup 1)))
2181    (set (match_dup 2)
2182         (compare:CC (match_dup 0)
2183                     (const_int 0)))]
2184   ""
2185   [(set_attr "type" "add")
2186    (set_attr "dot" "yes")
2187    (set_attr "length" "4,8")])
2190 (define_insn "clz<mode>2"
2191   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2192         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2193   ""
2194   "cntlz<wd> %0,%1"
2195   [(set_attr "type" "cntlz")])
2197 (define_expand "ctz<mode>2"
2198   [(set (match_dup 2)
2199         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2200    (set (match_dup 3)
2201         (and:GPR (match_dup 1)
2202                  (match_dup 2)))
2203    (set (match_dup 4)
2204         (clz:GPR (match_dup 3)))
2205    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2206                    (minus:GPR (match_dup 5)
2207                               (match_dup 4)))
2208               (clobber (reg:GPR CA_REGNO))])]
2209   ""
2211   if (TARGET_CTZ)
2212     {
2213       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2214       DONE;
2215     }
2217   operands[2] = gen_reg_rtx (<MODE>mode);
2218   operands[3] = gen_reg_rtx (<MODE>mode);
2219   operands[4] = gen_reg_rtx (<MODE>mode);
2220   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2223 (define_insn "ctz<mode>2_hw"
2224   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2226   "TARGET_CTZ"
2227   "cnttz<wd> %0,%1"
2228   [(set_attr "type" "cntlz")])
2230 (define_expand "ffs<mode>2"
2231   [(set (match_dup 2)
2232         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2233    (set (match_dup 3)
2234         (and:GPR (match_dup 1)
2235                  (match_dup 2)))
2236    (set (match_dup 4)
2237         (clz:GPR (match_dup 3)))
2238    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2239                    (minus:GPR (match_dup 5)
2240                               (match_dup 4)))
2241               (clobber (reg:GPR CA_REGNO))])]
2242   ""
2244   operands[2] = gen_reg_rtx (<MODE>mode);
2245   operands[3] = gen_reg_rtx (<MODE>mode);
2246   operands[4] = gen_reg_rtx (<MODE>mode);
2247   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2251 (define_expand "popcount<mode>2"
2252   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2253         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2254   "TARGET_POPCNTB || TARGET_POPCNTD"
2256   rs6000_emit_popcount (operands[0], operands[1]);
2257   DONE;
2260 (define_insn "popcntb<mode>2"
2261   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2262         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2263                     UNSPEC_POPCNTB))]
2264   "TARGET_POPCNTB"
2265   "popcntb %0,%1"
2266   [(set_attr "type" "popcnt")])
2268 (define_insn "popcntd<mode>2"
2269   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2270         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2271   "TARGET_POPCNTD"
2272   "popcnt<wd> %0,%1"
2273   [(set_attr "type" "popcnt")])
2276 (define_expand "parity<mode>2"
2277   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2278         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2279   "TARGET_POPCNTB"
2281   rs6000_emit_parity (operands[0], operands[1]);
2282   DONE;
2285 (define_insn "parity<mode>2_cmpb"
2286   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2288   "TARGET_CMPB && TARGET_POPCNTB"
2289   "prty<wd> %0,%1"
2290   [(set_attr "type" "popcnt")])
2293 ;; Since the hardware zeros the upper part of the register, save generating the
2294 ;; AND immediate if we are converting to unsigned
2295 (define_insn "*bswaphi2_extenddi"
2296   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2297         (zero_extend:DI
2298          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2299   "TARGET_POWERPC64"
2300   "lhbrx %0,%y1"
2301   [(set_attr "length" "4")
2302    (set_attr "type" "load")])
2304 (define_insn "*bswaphi2_extendsi"
2305   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2306         (zero_extend:SI
2307          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2308   ""
2309   "lhbrx %0,%y1"
2310   [(set_attr "length" "4")
2311    (set_attr "type" "load")])
2313 (define_expand "bswaphi2"
2314   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2315                    (bswap:HI
2316                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2317               (clobber (match_scratch:SI 2 ""))])]
2318   ""
2320   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2321     operands[1] = force_reg (HImode, operands[1]);
2324 (define_insn "bswaphi2_internal"
2325   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2326         (bswap:HI
2327          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2328    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2329   ""
2330   "@
2331    lhbrx %0,%y1
2332    sthbrx %1,%y0
2333    #"
2334   [(set_attr "length" "4,4,12")
2335    (set_attr "type" "load,store,*")])
2337 (define_split
2338   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2339         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2340    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2341   "reload_completed"
2342   [(set (match_dup 3)
2343         (and:SI (lshiftrt:SI (match_dup 4)
2344                              (const_int 8))
2345                 (const_int 255)))
2346    (set (match_dup 2)
2347         (and:SI (ashift:SI (match_dup 4)
2348                            (const_int 8))
2349                 (const_int 65280)))             ;; 0xff00
2350    (set (match_dup 3)
2351         (ior:SI (match_dup 3)
2352                 (match_dup 2)))]
2353   "
2355   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2356   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2359 (define_insn "*bswapsi2_extenddi"
2360   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2361         (zero_extend:DI
2362          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2363   "TARGET_POWERPC64"
2364   "lwbrx %0,%y1"
2365   [(set_attr "length" "4")
2366    (set_attr "type" "load")])
2368 (define_expand "bswapsi2"
2369   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2370         (bswap:SI
2371          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2372   ""
2374   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2375     operands[1] = force_reg (SImode, operands[1]);
2378 (define_insn "*bswapsi2_internal"
2379   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2380         (bswap:SI
2381          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2382   ""
2383   "@
2384    lwbrx %0,%y1
2385    stwbrx %1,%y0
2386    #"
2387   [(set_attr "length" "4,4,12")
2388    (set_attr "type" "load,store,*")])
2390 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2391 ;; zero_extract insns do not change for -mlittle.
2392 (define_split
2393   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2394         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2395   "reload_completed"
2396   [(set (match_dup 0)                                   ; DABC
2397         (rotate:SI (match_dup 1)
2398                    (const_int 24)))
2399    (set (match_dup 0)                                   ; DCBC
2400         (ior:SI (and:SI (ashift:SI (match_dup 1)
2401                                    (const_int 8))
2402                         (const_int 16711680))
2403                 (and:SI (match_dup 0)
2404                         (const_int -16711681))))
2405    (set (match_dup 0)                                   ; DCBA
2406         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2407                                      (const_int 24))
2408                         (const_int 255))
2409                 (and:SI (match_dup 0)
2410                         (const_int -256))))
2412   ]
2413   "")
2415 (define_expand "bswapdi2"
2416   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2417                    (bswap:DI
2418                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2419               (clobber (match_scratch:DI 2 ""))
2420               (clobber (match_scratch:DI 3 ""))])]
2421   ""
2423   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2424     operands[1] = force_reg (DImode, operands[1]);
2426   if (!TARGET_POWERPC64)
2427     {
2428       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2429          that uses 64-bit registers needs the same scratch registers as 64-bit
2430          mode.  */
2431       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2432       DONE;
2433     }
2436 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2437 (define_insn "*bswapdi2_ldbrx"
2438   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2439         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2440    (clobber (match_scratch:DI 2 "=X,X,&r"))
2441    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2442   "TARGET_POWERPC64 && TARGET_LDBRX
2443    && (REG_P (operands[0]) || REG_P (operands[1]))"
2444   "@
2445    ldbrx %0,%y1
2446    stdbrx %1,%y0
2447    #"
2448   [(set_attr "length" "4,4,36")
2449    (set_attr "type" "load,store,*")])
2451 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2452 (define_insn "*bswapdi2_64bit"
2453   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2454         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2455    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2456    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2457   "TARGET_POWERPC64 && !TARGET_LDBRX
2458    && (REG_P (operands[0]) || REG_P (operands[1]))
2459    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2460    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2461   "#"
2462   [(set_attr "length" "16,12,36")])
2464 (define_split
2465   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2466         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2467    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2468    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2469   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2470   [(const_int 0)]
2471   "
2473   rtx dest   = operands[0];
2474   rtx src    = operands[1];
2475   rtx op2    = operands[2];
2476   rtx op3    = operands[3];
2477   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2478                                     BYTES_BIG_ENDIAN ? 4 : 0);
2479   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2480                                      BYTES_BIG_ENDIAN ? 4 : 0);
2481   rtx addr1;
2482   rtx addr2;
2483   rtx word1;
2484   rtx word2;
2486   addr1 = XEXP (src, 0);
2487   if (GET_CODE (addr1) == PLUS)
2488     {
2489       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2490       if (TARGET_AVOID_XFORM)
2491         {
2492           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2493           addr2 = op2;
2494         }
2495       else
2496         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2497     }
2498   else if (TARGET_AVOID_XFORM)
2499     {
2500       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2501       addr2 = op2;
2502     }
2503   else
2504     {
2505       emit_move_insn (op2, GEN_INT (4));
2506       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2507     }
2509   word1 = change_address (src, SImode, addr1);
2510   word2 = change_address (src, SImode, addr2);
2512   if (BYTES_BIG_ENDIAN)
2513     {
2514       emit_insn (gen_bswapsi2 (op3_32, word2));
2515       emit_insn (gen_bswapsi2 (dest_32, word1));
2516     }
2517   else
2518     {
2519       emit_insn (gen_bswapsi2 (op3_32, word1));
2520       emit_insn (gen_bswapsi2 (dest_32, word2));
2521     }
2523   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2524   emit_insn (gen_iordi3 (dest, dest, op3));
2525   DONE;
2528 (define_split
2529   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2530         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2531    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2532    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2533   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2534   [(const_int 0)]
2535   "
2537   rtx dest   = operands[0];
2538   rtx src    = operands[1];
2539   rtx op2    = operands[2];
2540   rtx op3    = operands[3];
2541   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2542                                     BYTES_BIG_ENDIAN ? 4 : 0);
2543   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2544                                     BYTES_BIG_ENDIAN ? 4 : 0);
2545   rtx addr1;
2546   rtx addr2;
2547   rtx word1;
2548   rtx word2;
2550   addr1 = XEXP (dest, 0);
2551   if (GET_CODE (addr1) == PLUS)
2552     {
2553       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2554       if (TARGET_AVOID_XFORM)
2555         {
2556           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2557           addr2 = op2;
2558         }
2559       else
2560         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2561     }
2562   else if (TARGET_AVOID_XFORM)
2563     {
2564       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2565       addr2 = op2;
2566     }
2567   else
2568     {
2569       emit_move_insn (op2, GEN_INT (4));
2570       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2571     }
2573   word1 = change_address (dest, SImode, addr1);
2574   word2 = change_address (dest, SImode, addr2);
2576   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2578   if (BYTES_BIG_ENDIAN)
2579     {
2580       emit_insn (gen_bswapsi2 (word1, src_si));
2581       emit_insn (gen_bswapsi2 (word2, op3_si));
2582     }
2583   else
2584     {
2585       emit_insn (gen_bswapsi2 (word2, src_si));
2586       emit_insn (gen_bswapsi2 (word1, op3_si));
2587     }
2588   DONE;
2591 (define_split
2592   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2593         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2594    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2595    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2596   "TARGET_POWERPC64 && reload_completed"
2597   [(const_int 0)]
2598   "
2600   rtx dest    = operands[0];
2601   rtx src     = operands[1];
2602   rtx op2     = operands[2];
2603   rtx op3     = operands[3];
2604   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2605   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2606   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2607   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2608   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2610   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2611   emit_insn (gen_bswapsi2 (dest_si, src_si));
2612   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2613   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2614   emit_insn (gen_iordi3 (dest, dest, op3));
2615   DONE;
2618 (define_insn "bswapdi2_32bit"
2619   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2620         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2621    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2622   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2623   "#"
2624   [(set_attr "length" "16,12,36")])
2626 (define_split
2627   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2628         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2629    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2630   "!TARGET_POWERPC64 && reload_completed"
2631   [(const_int 0)]
2632   "
2634   rtx dest  = operands[0];
2635   rtx src   = operands[1];
2636   rtx op2   = operands[2];
2637   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2638   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2639   rtx addr1;
2640   rtx addr2;
2641   rtx word1;
2642   rtx word2;
2644   addr1 = XEXP (src, 0);
2645   if (GET_CODE (addr1) == PLUS)
2646     {
2647       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2648       if (TARGET_AVOID_XFORM
2649           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2650         {
2651           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2652           addr2 = op2;
2653         }
2654       else
2655         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2656     }
2657   else if (TARGET_AVOID_XFORM
2658            || REGNO (addr1) == REGNO (dest2))
2659     {
2660       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2661       addr2 = op2;
2662     }
2663   else
2664     {
2665       emit_move_insn (op2, GEN_INT (4));
2666       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2667     }
2669   word1 = change_address (src, SImode, addr1);
2670   word2 = change_address (src, SImode, addr2);
2672   emit_insn (gen_bswapsi2 (dest2, word1));
2673   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2674      thus allowing us to omit an early clobber on the output.  */
2675   emit_insn (gen_bswapsi2 (dest1, word2));
2676   DONE;
2679 (define_split
2680   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2681         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2682    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2683   "!TARGET_POWERPC64 && reload_completed"
2684   [(const_int 0)]
2685   "
2687   rtx dest = operands[0];
2688   rtx src  = operands[1];
2689   rtx op2  = operands[2];
2690   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2691   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2692   rtx addr1;
2693   rtx addr2;
2694   rtx word1;
2695   rtx word2;
2697   addr1 = XEXP (dest, 0);
2698   if (GET_CODE (addr1) == PLUS)
2699     {
2700       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2701       if (TARGET_AVOID_XFORM)
2702         {
2703           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2704           addr2 = op2;
2705         }
2706       else
2707         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2708     }
2709   else if (TARGET_AVOID_XFORM)
2710     {
2711       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2712       addr2 = op2;
2713     }
2714   else
2715     {
2716       emit_move_insn (op2, GEN_INT (4));
2717       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2718     }
2720   word1 = change_address (dest, SImode, addr1);
2721   word2 = change_address (dest, SImode, addr2);
2723   emit_insn (gen_bswapsi2 (word2, src1));
2724   emit_insn (gen_bswapsi2 (word1, src2));
2725   DONE;
2728 (define_split
2729   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2730         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2731    (clobber (match_operand:SI 2 "" ""))]
2732   "!TARGET_POWERPC64 && reload_completed"
2733   [(const_int 0)]
2734   "
2736   rtx dest  = operands[0];
2737   rtx src   = operands[1];
2738   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2739   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2740   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2741   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2743   emit_insn (gen_bswapsi2 (dest1, src2));
2744   emit_insn (gen_bswapsi2 (dest2, src1));
2745   DONE;
2749 (define_insn "mul<mode>3"
2750   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2751         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2752                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2753   ""
2754   "@
2755    mull<wd> %0,%1,%2
2756    mulli %0,%1,%2"
2757    [(set_attr "type" "mul")
2758     (set (attr "size")
2759       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2760                 (const_string "8")
2761              (match_operand:GPR 2 "short_cint_operand" "")
2762                 (const_string "16")]
2763         (const_string "<bits>")))])
2765 (define_insn_and_split "*mul<mode>3_dot"
2766   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2767         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2768                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2769                     (const_int 0)))
2770    (clobber (match_scratch:GPR 0 "=r,r"))]
2771   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2772   "@
2773    mull<wd>. %0,%1,%2
2774    #"
2775   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2776   [(set (match_dup 0)
2777         (mult:GPR (match_dup 1)
2778                   (match_dup 2)))
2779    (set (match_dup 3)
2780         (compare:CC (match_dup 0)
2781                     (const_int 0)))]
2782   ""
2783   [(set_attr "type" "mul")
2784    (set_attr "size" "<bits>")
2785    (set_attr "dot" "yes")
2786    (set_attr "length" "4,8")])
2788 (define_insn_and_split "*mul<mode>3_dot2"
2789   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2790         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2791                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2792                     (const_int 0)))
2793    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2794         (mult:GPR (match_dup 1)
2795                   (match_dup 2)))]
2796   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2797   "@
2798    mull<wd>. %0,%1,%2
2799    #"
2800   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2801   [(set (match_dup 0)
2802         (mult:GPR (match_dup 1)
2803                   (match_dup 2)))
2804    (set (match_dup 3)
2805         (compare:CC (match_dup 0)
2806                     (const_int 0)))]
2807   ""
2808   [(set_attr "type" "mul")
2809    (set_attr "size" "<bits>")
2810    (set_attr "dot" "yes")
2811    (set_attr "length" "4,8")])
2814 (define_expand "<su>mul<mode>3_highpart"
2815   [(set (match_operand:GPR 0 "gpc_reg_operand")
2816         (subreg:GPR
2817           (mult:<DMODE> (any_extend:<DMODE>
2818                           (match_operand:GPR 1 "gpc_reg_operand"))
2819                         (any_extend:<DMODE>
2820                           (match_operand:GPR 2 "gpc_reg_operand")))
2821          0))]
2822   ""
2824   if (<MODE>mode == SImode && TARGET_POWERPC64)
2825     {
2826       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2827                                              operands[2]));
2828       DONE;
2829     }
2831   if (!WORDS_BIG_ENDIAN)
2832     {
2833       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2834                                                  operands[2]));
2835       DONE;
2836     }
2839 (define_insn "*<su>mul<mode>3_highpart"
2840   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2841         (subreg:GPR
2842           (mult:<DMODE> (any_extend:<DMODE>
2843                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2844                         (any_extend:<DMODE>
2845                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2846          0))]
2847   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2848   "mulh<wd><u> %0,%1,%2"
2849   [(set_attr "type" "mul")
2850    (set_attr "size" "<bits>")])
2852 (define_insn "<su>mulsi3_highpart_le"
2853   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2854         (subreg:SI
2855           (mult:DI (any_extend:DI
2856                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2857                    (any_extend:DI
2858                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2859          4))]
2860   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2861   "mulhw<u> %0,%1,%2"
2862   [(set_attr "type" "mul")])
2864 (define_insn "<su>muldi3_highpart_le"
2865   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2866         (subreg:DI
2867           (mult:TI (any_extend:TI
2868                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2869                    (any_extend:TI
2870                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2871          8))]
2872   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2873   "mulhd<u> %0,%1,%2"
2874   [(set_attr "type" "mul")
2875    (set_attr "size" "64")])
2877 (define_insn "<su>mulsi3_highpart_64"
2878   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2879         (truncate:SI
2880           (lshiftrt:DI
2881             (mult:DI (any_extend:DI
2882                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2883                      (any_extend:DI
2884                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2885             (const_int 32))))]
2886   "TARGET_POWERPC64"
2887   "mulhw<u> %0,%1,%2"
2888   [(set_attr "type" "mul")])
2890 (define_expand "<u>mul<mode><dmode>3"
2891   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2892         (mult:<DMODE> (any_extend:<DMODE>
2893                         (match_operand:GPR 1 "gpc_reg_operand"))
2894                       (any_extend:<DMODE>
2895                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2896   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2898   rtx l = gen_reg_rtx (<MODE>mode);
2899   rtx h = gen_reg_rtx (<MODE>mode);
2900   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2901   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2902   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2903   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2904   DONE;
2907 (define_insn "*maddld4"
2908   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2909         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2910                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2911                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2912   "TARGET_MADDLD"
2913   "maddld %0,%1,%2,%3"
2914   [(set_attr "type" "mul")])
2916 (define_insn "udiv<mode>3"
2917   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2918         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2919                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2920   ""
2921   "div<wd>u %0,%1,%2"
2922   [(set_attr "type" "div")
2923    (set_attr "size" "<bits>")])
2926 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2927 ;; modulus.  If it isn't a power of two, force operands into register and do
2928 ;; a normal divide.
2929 (define_expand "div<mode>3"
2930   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2931         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2932                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2933   ""
2935   if (CONST_INT_P (operands[2])
2936       && INTVAL (operands[2]) > 0
2937       && exact_log2 (INTVAL (operands[2])) >= 0)
2938     {
2939       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2940       DONE;
2941     }
2943   operands[2] = force_reg (<MODE>mode, operands[2]);
2946 (define_insn "*div<mode>3"
2947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2948         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2949                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2950   ""
2951   "div<wd> %0,%1,%2"
2952   [(set_attr "type" "div")
2953    (set_attr "size" "<bits>")])
2955 (define_insn "div<mode>3_sra"
2956   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2957         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2958                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2959    (clobber (reg:GPR CA_REGNO))]
2960   ""
2961   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2962   [(set_attr "type" "two")
2963    (set_attr "length" "8")])
2965 (define_insn_and_split "*div<mode>3_sra_dot"
2966   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2967         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2968                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2969                     (const_int 0)))
2970    (clobber (match_scratch:GPR 0 "=r,r"))
2971    (clobber (reg:GPR CA_REGNO))]
2972   "<MODE>mode == Pmode"
2973   "@
2974    sra<wd>i %0,%1,%p2\;addze. %0,%0
2975    #"
2976   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2977   [(parallel [(set (match_dup 0)
2978                    (div:GPR (match_dup 1)
2979                             (match_dup 2)))
2980               (clobber (reg:GPR CA_REGNO))])
2981    (set (match_dup 3)
2982         (compare:CC (match_dup 0)
2983                     (const_int 0)))]
2984   ""
2985   [(set_attr "type" "two")
2986    (set_attr "length" "8,12")
2987    (set_attr "cell_micro" "not")])
2989 (define_insn_and_split "*div<mode>3_sra_dot2"
2990   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2991         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2992                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2993                     (const_int 0)))
2994    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2995         (div:GPR (match_dup 1)
2996                  (match_dup 2)))
2997    (clobber (reg:GPR CA_REGNO))]
2998   "<MODE>mode == Pmode"
2999   "@
3000    sra<wd>i %0,%1,%p2\;addze. %0,%0
3001    #"
3002   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3003   [(parallel [(set (match_dup 0)
3004                    (div:GPR (match_dup 1)
3005                             (match_dup 2)))
3006               (clobber (reg:GPR CA_REGNO))])
3007    (set (match_dup 3)
3008         (compare:CC (match_dup 0)
3009                     (const_int 0)))]
3010   ""
3011   [(set_attr "type" "two")
3012    (set_attr "length" "8,12")
3013    (set_attr "cell_micro" "not")])
3015 (define_expand "mod<mode>3"
3016   [(set (match_operand:GPR 0 "gpc_reg_operand")
3017         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3018                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3019   ""
3021   int i;
3022   rtx temp1;
3023   rtx temp2;
3025   if (GET_CODE (operands[2]) != CONST_INT
3026       || INTVAL (operands[2]) <= 0
3027       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3028     {
3029       if (!TARGET_MODULO)
3030         FAIL;
3032       operands[2] = force_reg (<MODE>mode, operands[2]);
3033     }
3034   else
3035     {
3036       temp1 = gen_reg_rtx (<MODE>mode);
3037       temp2 = gen_reg_rtx (<MODE>mode);
3039       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3040       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3041       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3042       DONE;
3043     }
3046 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3047 ;; mod, prefer putting the result of mod into a different register
3048 (define_insn "*mod<mode>3"
3049   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3050         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3051                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3052   "TARGET_MODULO"
3053   "mods<wd> %0,%1,%2"
3054   [(set_attr "type" "div")
3055    (set_attr "size" "<bits>")])
3058 (define_insn "umod<mode>3"
3059   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3060         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3061                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3062   "TARGET_MODULO"
3063   "modu<wd> %0,%1,%2"
3064   [(set_attr "type" "div")
3065    (set_attr "size" "<bits>")])
3067 ;; On machines with modulo support, do a combined div/mod the old fashioned
3068 ;; method, since the multiply/subtract is faster than doing the mod instruction
3069 ;; after a divide.
3071 (define_peephole2
3072   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3073         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3074                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3075    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3076         (mod:GPR (match_dup 1)
3077                  (match_dup 2)))]
3078   "TARGET_MODULO
3079    && ! reg_mentioned_p (operands[0], operands[1])
3080    && ! reg_mentioned_p (operands[0], operands[2])
3081    && ! reg_mentioned_p (operands[3], operands[1])
3082    && ! reg_mentioned_p (operands[3], operands[2])"
3083   [(set (match_dup 0)
3084         (div:GPR (match_dup 1)
3085                  (match_dup 2)))
3086    (set (match_dup 3)
3087         (mult:GPR (match_dup 0)
3088                   (match_dup 2)))
3089    (set (match_dup 3)
3090         (minus:GPR (match_dup 1)
3091                    (match_dup 3)))])
3093 (define_peephole2
3094   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3095         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3096                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3097    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3098         (umod:GPR (match_dup 1)
3099                   (match_dup 2)))]
3100   "TARGET_MODULO
3101    && ! reg_mentioned_p (operands[0], operands[1])
3102    && ! reg_mentioned_p (operands[0], operands[2])
3103    && ! reg_mentioned_p (operands[3], operands[1])
3104    && ! reg_mentioned_p (operands[3], operands[2])"
3105   [(set (match_dup 0)
3106         (div:GPR (match_dup 1)
3107                  (match_dup 2)))
3108    (set (match_dup 3)
3109         (mult:GPR (match_dup 0)
3110                   (match_dup 2)))
3111    (set (match_dup 3)
3112         (minus:GPR (match_dup 1)
3113                    (match_dup 3)))])
3116 ;; Logical instructions
3117 ;; The logical instructions are mostly combined by using match_operator,
3118 ;; but the plain AND insns are somewhat different because there is no
3119 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3120 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3122 (define_expand "and<mode>3"
3123   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3124         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3125                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3126   ""
3128   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3129     {
3130       rs6000_split_logical (operands, AND, false, false, false);
3131       DONE;
3132     }
3134   if (CONST_INT_P (operands[2]))
3135     {
3136       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3137         {
3138           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3139           DONE;
3140         }
3142       if (logical_const_operand (operands[2], <MODE>mode)
3143           && rs6000_gen_cell_microcode)
3144         {
3145           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3146           DONE;
3147         }
3149       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3150         {
3151           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3152           DONE;
3153         }
3155       operands[2] = force_reg (<MODE>mode, operands[2]);
3156     }
3160 (define_insn "and<mode>3_imm"
3161   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3162         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3163                  (match_operand:GPR 2 "logical_const_operand" "n")))
3164    (clobber (match_scratch:CC 3 "=x"))]
3165   "rs6000_gen_cell_microcode
3166    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3167   "andi%e2. %0,%1,%u2"
3168   [(set_attr "type" "logical")
3169    (set_attr "dot" "yes")])
3171 (define_insn_and_split "*and<mode>3_imm_dot"
3172   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3173         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3174                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3175                     (const_int 0)))
3176    (clobber (match_scratch:GPR 0 "=r,r"))
3177    (clobber (match_scratch:CC 4 "=X,x"))]
3178   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3179    && rs6000_gen_cell_microcode
3180    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3181   "@
3182    andi%e2. %0,%1,%u2
3183    #"
3184   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3185   [(parallel [(set (match_dup 0)
3186                    (and:GPR (match_dup 1)
3187                             (match_dup 2)))
3188               (clobber (match_dup 4))])
3189    (set (match_dup 3)
3190         (compare:CC (match_dup 0)
3191                     (const_int 0)))]
3192   ""
3193   [(set_attr "type" "logical")
3194    (set_attr "dot" "yes")
3195    (set_attr "length" "4,8")])
3197 (define_insn_and_split "*and<mode>3_imm_dot2"
3198   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3199         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3200                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3201                     (const_int 0)))
3202    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3203         (and:GPR (match_dup 1)
3204                  (match_dup 2)))
3205    (clobber (match_scratch:CC 4 "=X,x"))]
3206   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3207    && rs6000_gen_cell_microcode
3208    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3209   "@
3210    andi%e2. %0,%1,%u2
3211    #"
3212   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3213   [(parallel [(set (match_dup 0)
3214                    (and:GPR (match_dup 1)
3215                             (match_dup 2)))
3216               (clobber (match_dup 4))])
3217    (set (match_dup 3)
3218         (compare:CC (match_dup 0)
3219                     (const_int 0)))]
3220   ""
3221   [(set_attr "type" "logical")
3222    (set_attr "dot" "yes")
3223    (set_attr "length" "4,8")])
3225 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3226   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3227         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3228                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3229                     (const_int 0)))
3230    (clobber (match_scratch:GPR 0 "=r,r"))]
3231   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3232    && rs6000_gen_cell_microcode"
3233   "@
3234    andi%e2. %0,%1,%u2
3235    #"
3236   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3237   [(set (match_dup 0)
3238         (and:GPR (match_dup 1)
3239                  (match_dup 2)))
3240    (set (match_dup 3)
3241         (compare:CC (match_dup 0)
3242                     (const_int 0)))]
3243   ""
3244   [(set_attr "type" "logical")
3245    (set_attr "dot" "yes")
3246    (set_attr "length" "4,8")])
3248 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3249   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3250         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3251                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3252                     (const_int 0)))
3253    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3254         (and:GPR (match_dup 1)
3255                  (match_dup 2)))]
3256   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3257    && rs6000_gen_cell_microcode"
3258   "@
3259    andi%e2. %0,%1,%u2
3260    #"
3261   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3262   [(set (match_dup 0)
3263         (and:GPR (match_dup 1)
3264                  (match_dup 2)))
3265    (set (match_dup 3)
3266         (compare:CC (match_dup 0)
3267                     (const_int 0)))]
3268   ""
3269   [(set_attr "type" "logical")
3270    (set_attr "dot" "yes")
3271    (set_attr "length" "4,8")])
3273 (define_insn "*and<mode>3_imm_dot_shifted"
3274   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3275         (compare:CC
3276           (and:GPR
3277             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3278                           (match_operand:SI 4 "const_int_operand" "n"))
3279             (match_operand:GPR 2 "const_int_operand" "n"))
3280           (const_int 0)))
3281    (clobber (match_scratch:GPR 0 "=r"))]
3282   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3283                                    << INTVAL (operands[4])),
3284                           DImode)
3285    && (<MODE>mode == Pmode
3286        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3287    && rs6000_gen_cell_microcode"
3289   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3290   return "andi%e2. %0,%1,%u2";
3292   [(set_attr "type" "logical")
3293    (set_attr "dot" "yes")])
3296 (define_insn "and<mode>3_mask"
3297   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3298         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3299                  (match_operand:GPR 2 "const_int_operand" "n")))]
3300   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3302   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3304   [(set_attr "type" "shift")])
3306 (define_insn_and_split "*and<mode>3_mask_dot"
3307   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3308         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3309                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3310                     (const_int 0)))
3311    (clobber (match_scratch:GPR 0 "=r,r"))]
3312   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3313    && rs6000_gen_cell_microcode
3314    && !logical_const_operand (operands[2], <MODE>mode)
3315    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3317   if (which_alternative == 0)
3318     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3319   else
3320     return "#";
3322   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3323   [(set (match_dup 0)
3324         (and:GPR (match_dup 1)
3325                  (match_dup 2)))
3326    (set (match_dup 3)
3327         (compare:CC (match_dup 0)
3328                     (const_int 0)))]
3329   ""
3330   [(set_attr "type" "shift")
3331    (set_attr "dot" "yes")
3332    (set_attr "length" "4,8")])
3334 (define_insn_and_split "*and<mode>3_mask_dot2"
3335   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3336         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3337                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3338                     (const_int 0)))
3339    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3340         (and:GPR (match_dup 1)
3341                  (match_dup 2)))]
3342   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3343    && rs6000_gen_cell_microcode
3344    && !logical_const_operand (operands[2], <MODE>mode)
3345    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3347   if (which_alternative == 0)
3348     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3349   else
3350     return "#";
3352   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3353   [(set (match_dup 0)
3354         (and:GPR (match_dup 1)
3355                  (match_dup 2)))
3356    (set (match_dup 3)
3357         (compare:CC (match_dup 0)
3358                     (const_int 0)))]
3359   ""
3360   [(set_attr "type" "shift")
3361    (set_attr "dot" "yes")
3362    (set_attr "length" "4,8")])
3365 (define_insn_and_split "*and<mode>3_2insn"
3366   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3367         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3368                  (match_operand:GPR 2 "const_int_operand" "n")))]
3369   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3370    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3371         || (logical_const_operand (operands[2], <MODE>mode)
3372             && rs6000_gen_cell_microcode))"
3373   "#"
3374   "&& 1"
3375   [(pc)]
3377   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3378   DONE;
3380   [(set_attr "type" "shift")
3381    (set_attr "length" "8")])
3383 (define_insn_and_split "*and<mode>3_2insn_dot"
3384   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3385         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3386                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3387                     (const_int 0)))
3388    (clobber (match_scratch:GPR 0 "=r,r"))]
3389   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3390    && rs6000_gen_cell_microcode
3391    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3392    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3393         || (logical_const_operand (operands[2], <MODE>mode)
3394             && rs6000_gen_cell_microcode))"
3395   "#"
3396   "&& reload_completed"
3397   [(pc)]
3399   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3400   DONE;
3402   [(set_attr "type" "shift")
3403    (set_attr "dot" "yes")
3404    (set_attr "length" "8,12")])
3406 (define_insn_and_split "*and<mode>3_2insn_dot2"
3407   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3408         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3409                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3410                     (const_int 0)))
3411    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3412         (and:GPR (match_dup 1)
3413                  (match_dup 2)))]
3414   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3415    && rs6000_gen_cell_microcode
3416    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3417    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3418         || (logical_const_operand (operands[2], <MODE>mode)
3419             && rs6000_gen_cell_microcode))"
3420   "#"
3421   "&& reload_completed"
3422   [(pc)]
3424   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3425   DONE;
3427   [(set_attr "type" "shift")
3428    (set_attr "dot" "yes")
3429    (set_attr "length" "8,12")])
3432 (define_expand "<code><mode>3"
3433   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3434         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3435                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3436   ""
3438   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3439     {
3440       rs6000_split_logical (operands, <CODE>, false, false, false);
3441       DONE;
3442     }
3444   if (non_logical_cint_operand (operands[2], <MODE>mode))
3445     {
3446       rtx tmp = ((!can_create_pseudo_p ()
3447                   || rtx_equal_p (operands[0], operands[1]))
3448                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3450       HOST_WIDE_INT value = INTVAL (operands[2]);
3451       HOST_WIDE_INT lo = value & 0xffff;
3452       HOST_WIDE_INT hi = value - lo;
3454       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3455       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3456       DONE;
3457     }
3459   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3460     operands[2] = force_reg (<MODE>mode, operands[2]);
3463 (define_split
3464   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3465         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3466                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3467   ""
3468   [(set (match_dup 3)
3469         (iorxor:GPR (match_dup 1)
3470                     (match_dup 4)))
3471    (set (match_dup 0)
3472         (iorxor:GPR (match_dup 3)
3473                     (match_dup 5)))]
3475   operands[3] = ((!can_create_pseudo_p ()
3476                   || rtx_equal_p (operands[0], operands[1]))
3477                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3479   HOST_WIDE_INT value = INTVAL (operands[2]);
3480   HOST_WIDE_INT lo = value & 0xffff;
3481   HOST_WIDE_INT hi = value - lo;
3483   operands[4] = GEN_INT (hi);
3484   operands[5] = GEN_INT (lo);
3487 (define_insn "*bool<mode>3_imm"
3488   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3489         (match_operator:GPR 3 "boolean_or_operator"
3490          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3491           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3492   ""
3493   "%q3i%e2 %0,%1,%u2"
3494   [(set_attr "type" "logical")])
3496 (define_insn "*bool<mode>3"
3497   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3498         (match_operator:GPR 3 "boolean_operator"
3499          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3500           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3501   ""
3502   "%q3 %0,%1,%2"
3503   [(set_attr "type" "logical")])
3505 (define_insn_and_split "*bool<mode>3_dot"
3506   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3507         (compare:CC (match_operator:GPR 3 "boolean_operator"
3508          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3509           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3510          (const_int 0)))
3511    (clobber (match_scratch:GPR 0 "=r,r"))]
3512   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3513   "@
3514    %q3. %0,%1,%2
3515    #"
3516   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3517   [(set (match_dup 0)
3518         (match_dup 3))
3519    (set (match_dup 4)
3520         (compare:CC (match_dup 0)
3521                     (const_int 0)))]
3522   ""
3523   [(set_attr "type" "logical")
3524    (set_attr "dot" "yes")
3525    (set_attr "length" "4,8")])
3527 (define_insn_and_split "*bool<mode>3_dot2"
3528   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3529         (compare:CC (match_operator:GPR 3 "boolean_operator"
3530          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3531           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3532          (const_int 0)))
3533    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3534         (match_dup 3))]
3535   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3536   "@
3537    %q3. %0,%1,%2
3538    #"
3539   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3540   [(set (match_dup 0)
3541         (match_dup 3))
3542    (set (match_dup 4)
3543         (compare:CC (match_dup 0)
3544                     (const_int 0)))]
3545   ""
3546   [(set_attr "type" "logical")
3547    (set_attr "dot" "yes")
3548    (set_attr "length" "4,8")])
3551 (define_insn "*boolc<mode>3"
3552   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3553         (match_operator:GPR 3 "boolean_operator"
3554          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3555           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3556   ""
3557   "%q3 %0,%1,%2"
3558   [(set_attr "type" "logical")])
3560 (define_insn_and_split "*boolc<mode>3_dot"
3561   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3562         (compare:CC (match_operator:GPR 3 "boolean_operator"
3563          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3564           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3565          (const_int 0)))
3566    (clobber (match_scratch:GPR 0 "=r,r"))]
3567   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3568   "@
3569    %q3. %0,%1,%2
3570    #"
3571   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3572   [(set (match_dup 0)
3573         (match_dup 3))
3574    (set (match_dup 4)
3575         (compare:CC (match_dup 0)
3576                     (const_int 0)))]
3577   ""
3578   [(set_attr "type" "logical")
3579    (set_attr "dot" "yes")
3580    (set_attr "length" "4,8")])
3582 (define_insn_and_split "*boolc<mode>3_dot2"
3583   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3584         (compare:CC (match_operator:GPR 3 "boolean_operator"
3585          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3586           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3587          (const_int 0)))
3588    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3589         (match_dup 3))]
3590   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3591   "@
3592    %q3. %0,%1,%2
3593    #"
3594   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3595   [(set (match_dup 0)
3596         (match_dup 3))
3597    (set (match_dup 4)
3598         (compare:CC (match_dup 0)
3599                     (const_int 0)))]
3600   ""
3601   [(set_attr "type" "logical")
3602    (set_attr "dot" "yes")
3603    (set_attr "length" "4,8")])
3606 (define_insn "*boolcc<mode>3"
3607   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3608         (match_operator:GPR 3 "boolean_operator"
3609          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3610           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3611   ""
3612   "%q3 %0,%1,%2"
3613   [(set_attr "type" "logical")])
3615 (define_insn_and_split "*boolcc<mode>3_dot"
3616   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3617         (compare:CC (match_operator:GPR 3 "boolean_operator"
3618          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3619           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3620          (const_int 0)))
3621    (clobber (match_scratch:GPR 0 "=r,r"))]
3622   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3623   "@
3624    %q3. %0,%1,%2
3625    #"
3626   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3627   [(set (match_dup 0)
3628         (match_dup 3))
3629    (set (match_dup 4)
3630         (compare:CC (match_dup 0)
3631                     (const_int 0)))]
3632   ""
3633   [(set_attr "type" "logical")
3634    (set_attr "dot" "yes")
3635    (set_attr "length" "4,8")])
3637 (define_insn_and_split "*boolcc<mode>3_dot2"
3638   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3639         (compare:CC (match_operator:GPR 3 "boolean_operator"
3640          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3641           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3642          (const_int 0)))
3643    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3644         (match_dup 3))]
3645   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3646   "@
3647    %q3. %0,%1,%2
3648    #"
3649   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3650   [(set (match_dup 0)
3651         (match_dup 3))
3652    (set (match_dup 4)
3653         (compare:CC (match_dup 0)
3654                     (const_int 0)))]
3655   ""
3656   [(set_attr "type" "logical")
3657    (set_attr "dot" "yes")
3658    (set_attr "length" "4,8")])
3661 ;; TODO: Should have dots of this as well.
3662 (define_insn "*eqv<mode>3"
3663   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3664         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3665                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3666   ""
3667   "eqv %0,%1,%2"
3668   [(set_attr "type" "logical")])
3670 ;; Rotate-and-mask and insert.
3672 (define_insn "*rotl<mode>3_mask"
3673   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3674         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3675                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3676                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3677                  (match_operand:GPR 3 "const_int_operand" "n")))]
3678   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3680   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3682   [(set_attr "type" "shift")
3683    (set_attr "maybe_var_shift" "yes")])
3685 (define_insn_and_split "*rotl<mode>3_mask_dot"
3686   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3687         (compare:CC
3688           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3689                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3690                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3691                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3692           (const_int 0)))
3693    (clobber (match_scratch:GPR 0 "=r,r"))]
3694   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3695    && rs6000_gen_cell_microcode
3696    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3698   if (which_alternative == 0)
3699     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3700   else
3701     return "#";
3703   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3704   [(set (match_dup 0)
3705         (and:GPR (match_dup 4)
3706                  (match_dup 3)))
3707    (set (match_dup 5)
3708         (compare:CC (match_dup 0)
3709                     (const_int 0)))]
3710   ""
3711   [(set_attr "type" "shift")
3712    (set_attr "maybe_var_shift" "yes")
3713    (set_attr "dot" "yes")
3714    (set_attr "length" "4,8")])
3716 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3717   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3718         (compare:CC
3719           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3720                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3721                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3722                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3723           (const_int 0)))
3724    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3725         (and:GPR (match_dup 4)
3726                  (match_dup 3)))]
3727   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3728    && rs6000_gen_cell_microcode
3729    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3731   if (which_alternative == 0)
3732     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3733   else
3734     return "#";
3736   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3737   [(set (match_dup 0)
3738         (and:GPR (match_dup 4)
3739                  (match_dup 3)))
3740    (set (match_dup 5)
3741         (compare:CC (match_dup 0)
3742                     (const_int 0)))]
3743   ""
3744   [(set_attr "type" "shift")
3745    (set_attr "maybe_var_shift" "yes")
3746    (set_attr "dot" "yes")
3747    (set_attr "length" "4,8")])
3749 ; Special case for less-than-0.  We can do it with just one machine
3750 ; instruction, but the generic optimizers do not realise it is cheap.
3751 (define_insn "*lt0_disi"
3752   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3753         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3754                (const_int 0)))]
3755   "TARGET_POWERPC64"
3756   "rlwinm %0,%1,1,31,31"
3757   [(set_attr "type" "shift")])
3761 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3762 ; both are an AND so are the same precedence).
3763 (define_insn "*rotl<mode>3_insert"
3764   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3765         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3766                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3767                             (match_operand:SI 2 "const_int_operand" "n")])
3768                           (match_operand:GPR 3 "const_int_operand" "n"))
3769                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3770                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3771   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3772    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3774   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3776   [(set_attr "type" "insert")])
3777 ; FIXME: this needs an attr "size", so that the scheduler can see the
3778 ; difference between rlwimi and rldimi.  We also might want dot forms,
3779 ; but not for rlwimi on POWER4 and similar processors.
3781 (define_insn "*rotl<mode>3_insert_2"
3782   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3783         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3784                           (match_operand:GPR 6 "const_int_operand" "n"))
3785                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3786                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3787                             (match_operand:SI 2 "const_int_operand" "n")])
3788                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3789   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3790    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3792   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3794   [(set_attr "type" "insert")])
3796 ; There are also some forms without one of the ANDs.
3797 (define_insn "*rotl<mode>3_insert_3"
3798   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3799         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3800                           (match_operand:GPR 4 "const_int_operand" "n"))
3801                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3802                              (match_operand:SI 2 "const_int_operand" "n"))))]
3803   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3805   if (<MODE>mode == SImode)
3806     return "rlwimi %0,%1,%h2,0,31-%h2";
3807   else
3808     return "rldimi %0,%1,%H2,0";
3810   [(set_attr "type" "insert")])
3812 (define_insn "*rotl<mode>3_insert_4"
3813   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3814         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3815                           (match_operand:GPR 4 "const_int_operand" "n"))
3816                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3817                                (match_operand:SI 2 "const_int_operand" "n"))))]
3818   "<MODE>mode == SImode &&
3819    GET_MODE_PRECISION (<MODE>mode)
3820    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3822   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3823                          - INTVAL (operands[2]));
3824   if (<MODE>mode == SImode)
3825     return "rlwimi %0,%1,%h2,32-%h2,31";
3826   else
3827     return "rldimi %0,%1,%H2,64-%H2";
3829   [(set_attr "type" "insert")])
3832 ; This handles the important case of multiple-precision shifts.  There is
3833 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3834 (define_split
3835   [(set (match_operand:GPR 0 "gpc_reg_operand")
3836         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3837                              (match_operand:SI 3 "const_int_operand"))
3838                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3839                                (match_operand:SI 4 "const_int_operand"))))]
3840   "can_create_pseudo_p ()
3841    && INTVAL (operands[3]) + INTVAL (operands[4])
3842       >= GET_MODE_PRECISION (<MODE>mode)"
3843   [(set (match_dup 5)
3844         (lshiftrt:GPR (match_dup 2)
3845                       (match_dup 4)))
3846    (set (match_dup 0)
3847         (ior:GPR (and:GPR (match_dup 5)
3848                           (match_dup 6))
3849                  (ashift:GPR (match_dup 1)
3850                              (match_dup 3))))]
3852   unsigned HOST_WIDE_INT mask = 1;
3853   mask = (mask << INTVAL (operands[3])) - 1;
3854   operands[5] = gen_reg_rtx (<MODE>mode);
3855   operands[6] = GEN_INT (mask);
3858 (define_split
3859   [(set (match_operand:GPR 0 "gpc_reg_operand")
3860         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3861                                (match_operand:SI 4 "const_int_operand"))
3862                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3863                              (match_operand:SI 3 "const_int_operand"))))]
3864   "can_create_pseudo_p ()
3865    && INTVAL (operands[3]) + INTVAL (operands[4])
3866       >= GET_MODE_PRECISION (<MODE>mode)"
3867   [(set (match_dup 5)
3868         (lshiftrt:GPR (match_dup 2)
3869                       (match_dup 4)))
3870    (set (match_dup 0)
3871         (ior:GPR (and:GPR (match_dup 5)
3872                           (match_dup 6))
3873                  (ashift:GPR (match_dup 1)
3874                              (match_dup 3))))]
3876   unsigned HOST_WIDE_INT mask = 1;
3877   mask = (mask << INTVAL (operands[3])) - 1;
3878   operands[5] = gen_reg_rtx (<MODE>mode);
3879   operands[6] = GEN_INT (mask);
3883 ; Another important case is setting some bits to 1; we can do that with
3884 ; an insert instruction, in many cases.
3885 (define_insn_and_split "*ior<mode>_mask"
3886   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3888                  (match_operand:GPR 2 "const_int_operand" "n")))
3889    (clobber (match_scratch:GPR 3 "=r"))]
3890   "!logical_const_operand (operands[2], <MODE>mode)
3891    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3892   "#"
3893   "&& 1"
3894   [(set (match_dup 3)
3895         (const_int -1))
3896    (set (match_dup 0)
3897         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3898                                       (match_dup 4))
3899                           (match_dup 2))
3900                  (and:GPR (match_dup 1)
3901                           (match_dup 5))))]
3903   int nb, ne;
3904   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3905   if (GET_CODE (operands[3]) == SCRATCH)
3906     operands[3] = gen_reg_rtx (<MODE>mode);
3907   operands[4] = GEN_INT (ne);
3908   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3910   [(set_attr "type" "two")
3911    (set_attr "length" "8")])
3914 ;; Now the simple shifts.
3916 (define_insn "rotl<mode>3"
3917   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3919                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3920   ""
3921   "rotl<wd>%I2 %0,%1,%<hH>2"
3922   [(set_attr "type" "shift")
3923    (set_attr "maybe_var_shift" "yes")])
3925 (define_insn "*rotlsi3_64"
3926   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3927         (zero_extend:DI
3928             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3929                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3930   "TARGET_POWERPC64"
3931   "rotlw%I2 %0,%1,%h2"
3932   [(set_attr "type" "shift")
3933    (set_attr "maybe_var_shift" "yes")])
3935 (define_insn_and_split "*rotl<mode>3_dot"
3936   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3937         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3938                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3939                     (const_int 0)))
3940    (clobber (match_scratch:GPR 0 "=r,r"))]
3941   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3942   "@
3943    rotl<wd>%I2. %0,%1,%<hH>2
3944    #"
3945   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3946   [(set (match_dup 0)
3947         (rotate:GPR (match_dup 1)
3948                     (match_dup 2)))
3949    (set (match_dup 3)
3950         (compare:CC (match_dup 0)
3951                     (const_int 0)))]
3952   ""
3953   [(set_attr "type" "shift")
3954    (set_attr "maybe_var_shift" "yes")
3955    (set_attr "dot" "yes")
3956    (set_attr "length" "4,8")])
3958 (define_insn_and_split "*rotl<mode>3_dot2"
3959   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3960         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3961                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3962                     (const_int 0)))
3963    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3964         (rotate:GPR (match_dup 1)
3965                     (match_dup 2)))]
3966   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3967   "@
3968    rotl<wd>%I2. %0,%1,%<hH>2
3969    #"
3970   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3971   [(set (match_dup 0)
3972         (rotate:GPR (match_dup 1)
3973                     (match_dup 2)))
3974    (set (match_dup 3)
3975         (compare:CC (match_dup 0)
3976                     (const_int 0)))]
3977   ""
3978   [(set_attr "type" "shift")
3979    (set_attr "maybe_var_shift" "yes")
3980    (set_attr "dot" "yes")
3981    (set_attr "length" "4,8")])
3984 (define_insn "ashl<mode>3"
3985   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3986         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3987                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3988   ""
3989   "sl<wd>%I2 %0,%1,%<hH>2"
3990   [(set_attr "type" "shift")
3991    (set_attr "maybe_var_shift" "yes")])
3993 (define_insn "*ashlsi3_64"
3994   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3995         (zero_extend:DI
3996             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3997                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3998   "TARGET_POWERPC64"
3999   "slw%I2 %0,%1,%h2"
4000   [(set_attr "type" "shift")
4001    (set_attr "maybe_var_shift" "yes")])
4003 (define_insn_and_split "*ashl<mode>3_dot"
4004   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4005         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4006                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4007                     (const_int 0)))
4008    (clobber (match_scratch:GPR 0 "=r,r"))]
4009   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4010   "@
4011    sl<wd>%I2. %0,%1,%<hH>2
4012    #"
4013   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4014   [(set (match_dup 0)
4015         (ashift:GPR (match_dup 1)
4016                     (match_dup 2)))
4017    (set (match_dup 3)
4018         (compare:CC (match_dup 0)
4019                     (const_int 0)))]
4020   ""
4021   [(set_attr "type" "shift")
4022    (set_attr "maybe_var_shift" "yes")
4023    (set_attr "dot" "yes")
4024    (set_attr "length" "4,8")])
4026 (define_insn_and_split "*ashl<mode>3_dot2"
4027   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4028         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4029                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4030                     (const_int 0)))
4031    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4032         (ashift:GPR (match_dup 1)
4033                     (match_dup 2)))]
4034   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4035   "@
4036    sl<wd>%I2. %0,%1,%<hH>2
4037    #"
4038   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4039   [(set (match_dup 0)
4040         (ashift:GPR (match_dup 1)
4041                     (match_dup 2)))
4042    (set (match_dup 3)
4043         (compare:CC (match_dup 0)
4044                     (const_int 0)))]
4045   ""
4046   [(set_attr "type" "shift")
4047    (set_attr "maybe_var_shift" "yes")
4048    (set_attr "dot" "yes")
4049    (set_attr "length" "4,8")])
4051 ;; Pretend we have a memory form of extswsli until register allocation is done
4052 ;; so that we use LWZ to load the value from memory, instead of LWA.
4053 (define_insn_and_split "ashdi3_extswsli"
4054   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4055         (ashift:DI
4056          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4057          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4058   "TARGET_EXTSWSLI"
4059   "@
4060    extswsli %0,%1,%2
4061    #"
4062   "&& reload_completed && MEM_P (operands[1])"
4063   [(set (match_dup 3)
4064         (match_dup 1))
4065    (set (match_dup 0)
4066         (ashift:DI (sign_extend:DI (match_dup 3))
4067                    (match_dup 2)))]
4069   operands[3] = gen_lowpart (SImode, operands[0]);
4071   [(set_attr "type" "shift")
4072    (set_attr "maybe_var_shift" "no")])
4075 (define_insn_and_split "ashdi3_extswsli_dot"
4076   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4077         (compare:CC
4078          (ashift:DI
4079           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4080           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4081          (const_int 0)))
4082    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4083   "TARGET_EXTSWSLI"
4084   "@
4085    extswsli. %0,%1,%2
4086    #
4087    #
4088    #"
4089   "&& reload_completed
4090    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4091        || memory_operand (operands[1], SImode))"
4092   [(pc)]
4094   rtx dest = operands[0];
4095   rtx src = operands[1];
4096   rtx shift = operands[2];
4097   rtx cr = operands[3];
4098   rtx src2;
4100   if (!MEM_P (src))
4101     src2 = src;
4102   else
4103     {
4104       src2 = gen_lowpart (SImode, dest);
4105       emit_move_insn (src2, src);
4106     }
4108   if (REGNO (cr) == CR0_REGNO)
4109     {
4110       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4111       DONE;
4112     }
4114   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4115   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4116   DONE;
4118   [(set_attr "type" "shift")
4119    (set_attr "maybe_var_shift" "no")
4120    (set_attr "dot" "yes")
4121    (set_attr "length" "4,8,8,12")])
4123 (define_insn_and_split "ashdi3_extswsli_dot2"
4124   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4125         (compare:CC
4126          (ashift:DI
4127           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4128           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4129          (const_int 0)))
4130    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4131         (ashift:DI (sign_extend:DI (match_dup 1))
4132                    (match_dup 2)))]
4133   "TARGET_EXTSWSLI"
4134   "@
4135    extswsli. %0,%1,%2
4136    #
4137    #
4138    #"
4139   "&& reload_completed
4140    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4141        || memory_operand (operands[1], SImode))"
4142   [(pc)]
4144   rtx dest = operands[0];
4145   rtx src = operands[1];
4146   rtx shift = operands[2];
4147   rtx cr = operands[3];
4148   rtx src2;
4150   if (!MEM_P (src))
4151     src2 = src;
4152   else
4153     {
4154       src2 = gen_lowpart (SImode, dest);
4155       emit_move_insn (src2, src);
4156     }
4158   if (REGNO (cr) == CR0_REGNO)
4159     {
4160       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4161       DONE;
4162     }
4164   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4165   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4166   DONE;
4168   [(set_attr "type" "shift")
4169    (set_attr "maybe_var_shift" "no")
4170    (set_attr "dot" "yes")
4171    (set_attr "length" "4,8,8,12")])
4173 (define_insn "lshr<mode>3"
4174   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4175         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4176                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4177   ""
4178   "sr<wd>%I2 %0,%1,%<hH>2"
4179   [(set_attr "type" "shift")
4180    (set_attr "maybe_var_shift" "yes")])
4182 (define_insn "*lshrsi3_64"
4183   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4184         (zero_extend:DI
4185             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4186                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4187   "TARGET_POWERPC64"
4188   "srw%I2 %0,%1,%h2"
4189   [(set_attr "type" "shift")
4190    (set_attr "maybe_var_shift" "yes")])
4192 (define_insn_and_split "*lshr<mode>3_dot"
4193   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4194         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4195                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4196                     (const_int 0)))
4197    (clobber (match_scratch:GPR 0 "=r,r"))]
4198   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4199   "@
4200    sr<wd>%I2. %0,%1,%<hH>2
4201    #"
4202   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4203   [(set (match_dup 0)
4204         (lshiftrt:GPR (match_dup 1)
4205                       (match_dup 2)))
4206    (set (match_dup 3)
4207         (compare:CC (match_dup 0)
4208                     (const_int 0)))]
4209   ""
4210   [(set_attr "type" "shift")
4211    (set_attr "maybe_var_shift" "yes")
4212    (set_attr "dot" "yes")
4213    (set_attr "length" "4,8")])
4215 (define_insn_and_split "*lshr<mode>3_dot2"
4216   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4217         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4218                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4219                     (const_int 0)))
4220    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4221         (lshiftrt:GPR (match_dup 1)
4222                       (match_dup 2)))]
4223   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4224   "@
4225    sr<wd>%I2. %0,%1,%<hH>2
4226    #"
4227   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4228   [(set (match_dup 0)
4229         (lshiftrt:GPR (match_dup 1)
4230                       (match_dup 2)))
4231    (set (match_dup 3)
4232         (compare:CC (match_dup 0)
4233                     (const_int 0)))]
4234   ""
4235   [(set_attr "type" "shift")
4236    (set_attr "maybe_var_shift" "yes")
4237    (set_attr "dot" "yes")
4238    (set_attr "length" "4,8")])
4241 (define_insn "ashr<mode>3"
4242   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4243         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4244                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4245    (clobber (reg:GPR CA_REGNO))]
4246   ""
4247   "sra<wd>%I2 %0,%1,%<hH>2"
4248   [(set_attr "type" "shift")
4249    (set_attr "maybe_var_shift" "yes")])
4251 (define_insn "*ashrsi3_64"
4252   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4253         (sign_extend:DI
4254             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4255                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4256    (clobber (reg:SI CA_REGNO))]
4257   "TARGET_POWERPC64"
4258   "sraw%I2 %0,%1,%h2"
4259   [(set_attr "type" "shift")
4260    (set_attr "maybe_var_shift" "yes")])
4262 (define_insn_and_split "*ashr<mode>3_dot"
4263   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4264         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4265                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4266                     (const_int 0)))
4267    (clobber (match_scratch:GPR 0 "=r,r"))
4268    (clobber (reg:GPR CA_REGNO))]
4269   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4270   "@
4271    sra<wd>%I2. %0,%1,%<hH>2
4272    #"
4273   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4274   [(parallel [(set (match_dup 0)
4275                    (ashiftrt:GPR (match_dup 1)
4276                                  (match_dup 2)))
4277               (clobber (reg:GPR CA_REGNO))])
4278    (set (match_dup 3)
4279         (compare:CC (match_dup 0)
4280                     (const_int 0)))]
4281   ""
4282   [(set_attr "type" "shift")
4283    (set_attr "maybe_var_shift" "yes")
4284    (set_attr "dot" "yes")
4285    (set_attr "length" "4,8")])
4287 (define_insn_and_split "*ashr<mode>3_dot2"
4288   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4289         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4290                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4291                     (const_int 0)))
4292    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4293         (ashiftrt:GPR (match_dup 1)
4294                       (match_dup 2)))
4295    (clobber (reg:GPR CA_REGNO))]
4296   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4297   "@
4298    sra<wd>%I2. %0,%1,%<hH>2
4299    #"
4300   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4301   [(parallel [(set (match_dup 0)
4302                    (ashiftrt:GPR (match_dup 1)
4303                                  (match_dup 2)))
4304               (clobber (reg:GPR CA_REGNO))])
4305    (set (match_dup 3)
4306         (compare:CC (match_dup 0)
4307                     (const_int 0)))]
4308   ""
4309   [(set_attr "type" "shift")
4310    (set_attr "maybe_var_shift" "yes")
4311    (set_attr "dot" "yes")
4312    (set_attr "length" "4,8")])
4314 ;; Builtins to replace a division to generate FRE reciprocal estimate
4315 ;; instructions and the necessary fixup instructions
4316 (define_expand "recip<mode>3"
4317   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4318    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4319    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4320   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4322    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4323    DONE;
4326 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4327 ;; hardware division.  This is only done before register allocation and with
4328 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4329 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4330 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4331 (define_split
4332   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4333         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4334                     (match_operand 2 "gpc_reg_operand" "")))]
4335   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4336    && can_create_pseudo_p () && flag_finite_math_only
4337    && !flag_trapping_math && flag_reciprocal_math"
4338   [(const_int 0)]
4340   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4341   DONE;
4344 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4345 ;; appropriate fixup.
4346 (define_expand "rsqrt<mode>2"
4347   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4348    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4349   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4351   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4352   DONE;
4355 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4356 ;; modes here, and also add in conditional vsx/power8-vector support to access
4357 ;; values in the traditional Altivec registers if the appropriate
4358 ;; -mupper-regs-{df,sf} option is enabled.
4360 (define_expand "abs<mode>2"
4361   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4362         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4363   "TARGET_<MODE>_INSN"
4364   "")
4366 (define_insn "*abs<mode>2_fpr"
4367   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4368         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4369   "TARGET_<MODE>_FPR"
4370   "@
4371    fabs %0,%1
4372    xsabsdp %x0,%x1"
4373   [(set_attr "type" "fpsimple")
4374    (set_attr "fp_type" "fp_addsub_<Fs>")])
4376 (define_insn "*nabs<mode>2_fpr"
4377   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4378         (neg:SFDF
4379          (abs:SFDF
4380           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4381   "TARGET_<MODE>_FPR"
4382   "@
4383    fnabs %0,%1
4384    xsnabsdp %x0,%x1"
4385   [(set_attr "type" "fpsimple")
4386    (set_attr "fp_type" "fp_addsub_<Fs>")])
4388 (define_expand "neg<mode>2"
4389   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4390         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4391   "TARGET_<MODE>_INSN"
4392   "")
4394 (define_insn "*neg<mode>2_fpr"
4395   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4396         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4397   "TARGET_<MODE>_FPR"
4398   "@
4399    fneg %0,%1
4400    xsnegdp %x0,%x1"
4401   [(set_attr "type" "fpsimple")
4402    (set_attr "fp_type" "fp_addsub_<Fs>")])
4404 (define_expand "add<mode>3"
4405   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4406         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4407                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4408   "TARGET_<MODE>_INSN"
4409   "")
4411 (define_insn "*add<mode>3_fpr"
4412   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4413         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4414                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4415   "TARGET_<MODE>_FPR"
4416   "@
4417    fadd<Ftrad> %0,%1,%2
4418    xsadd<Fvsx> %x0,%x1,%x2"
4419   [(set_attr "type" "fp")
4420    (set_attr "fp_type" "fp_addsub_<Fs>")])
4422 (define_expand "sub<mode>3"
4423   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4424         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4425                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4426   "TARGET_<MODE>_INSN"
4427   "")
4429 (define_insn "*sub<mode>3_fpr"
4430   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4431         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4432                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4433   "TARGET_<MODE>_FPR"
4434   "@
4435    fsub<Ftrad> %0,%1,%2
4436    xssub<Fvsx> %x0,%x1,%x2"
4437   [(set_attr "type" "fp")
4438    (set_attr "fp_type" "fp_addsub_<Fs>")])
4440 (define_expand "mul<mode>3"
4441   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4442         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4443                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4444   "TARGET_<MODE>_INSN"
4445   "")
4447 (define_insn "*mul<mode>3_fpr"
4448   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4449         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4450                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4451   "TARGET_<MODE>_FPR"
4452   "@
4453    fmul<Ftrad> %0,%1,%2
4454    xsmul<Fvsx> %x0,%x1,%x2"
4455   [(set_attr "type" "dmul")
4456    (set_attr "fp_type" "fp_mul_<Fs>")])
4458 (define_expand "div<mode>3"
4459   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4460         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4461                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4462   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4463   "")
4465 (define_insn "*div<mode>3_fpr"
4466   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4467         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4468                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4469   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4470   "@
4471    fdiv<Ftrad> %0,%1,%2
4472    xsdiv<Fvsx> %x0,%x1,%x2"
4473   [(set_attr "type" "<Fs>div")
4474    (set_attr "fp_type" "fp_div_<Fs>")])
4476 (define_insn "*sqrt<mode>2_internal"
4477   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4478         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4479   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4480    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4481   "@
4482    fsqrt<Ftrad> %0,%1
4483    xssqrt<Fvsx> %x0,%x1"
4484   [(set_attr "type" "<Fs>sqrt")
4485    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4487 (define_expand "sqrt<mode>2"
4488   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4489         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4490   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4491    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4493   if (<MODE>mode == SFmode
4494       && TARGET_RECIP_PRECISION
4495       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4496       && !optimize_function_for_size_p (cfun)
4497       && flag_finite_math_only && !flag_trapping_math
4498       && flag_unsafe_math_optimizations)
4499     {
4500       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4501       DONE;
4502     }
4505 ;; Floating point reciprocal approximation
4506 (define_insn "fre<Fs>"
4507   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4508         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4509                      UNSPEC_FRES))]
4510   "TARGET_<FFRE>"
4511   "@
4512    fre<Ftrad> %0,%1
4513    xsre<Fvsx> %x0,%x1"
4514   [(set_attr "type" "fp")])
4516 (define_insn "*rsqrt<mode>2"
4517   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4518         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4519                      UNSPEC_RSQRT))]
4520   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4521   "@
4522    frsqrte<Ftrad> %0,%1
4523    xsrsqrte<Fvsx> %x0,%x1"
4524   [(set_attr "type" "fp")])
4526 ;; Floating point comparisons
4527 (define_insn "*cmp<mode>_fpr"
4528   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4529         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4530                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4531   "TARGET_<MODE>_FPR"
4532   "@
4533    fcmpu %0,%1,%2
4534    xscmpudp %0,%x1,%x2"
4535   [(set_attr "type" "fpcompare")])
4537 ;; Floating point conversions
4538 (define_expand "extendsfdf2"
4539   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4540         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4541   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4542   "")
4544 (define_insn_and_split "*extendsfdf2_fpr"
4545   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4546         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4547   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4548   "@
4549    #
4550    fmr %0,%1
4551    lfs%U1%X1 %0,%1
4552    #
4553    xscpsgndp %x0,%x1,%x1
4554    lxsspx %x0,%y1
4555    lxssp %0,%1"
4556   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4557   [(const_int 0)]
4559   emit_note (NOTE_INSN_DELETED);
4560   DONE;
4562   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4564 (define_expand "truncdfsf2"
4565   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4566         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4567   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4568   "")
4570 (define_insn "*truncdfsf2_fpr"
4571   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4572         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4573   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4574   "@
4575    frsp %0,%1
4576    xsrsp %x0,%x1"
4577   [(set_attr "type" "fp")])
4579 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4580 ;; builtins.c and optabs.c that are not correct for IBM long double
4581 ;; when little-endian.
4582 (define_expand "signbit<mode>2"
4583   [(set (match_dup 2)
4584         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4585    (set (match_dup 3)
4586         (subreg:DI (match_dup 2) 0))
4587    (set (match_dup 4)
4588         (match_dup 5))
4589    (set (match_operand:SI 0 "gpc_reg_operand" "")
4590         (match_dup 6))]
4591   "TARGET_HARD_FLOAT
4592    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4593    && (!FLOAT128_IEEE_P (<MODE>mode)
4594        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4596   if (FLOAT128_IEEE_P (<MODE>mode))
4597     {
4598       if (<MODE>mode == KFmode)
4599         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4600       else if (<MODE>mode == TFmode)
4601         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4602       else
4603         gcc_unreachable ();
4604       DONE;
4605     }
4606   operands[2] = gen_reg_rtx (DFmode);
4607   operands[3] = gen_reg_rtx (DImode);
4608   if (TARGET_POWERPC64)
4609     {
4610       operands[4] = gen_reg_rtx (DImode);
4611       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4612       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4613                                     WORDS_BIG_ENDIAN ? 4 : 0);
4614     }
4615   else
4616     {
4617       operands[4] = gen_reg_rtx (SImode);
4618       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4619                                     WORDS_BIG_ENDIAN ? 0 : 4);
4620       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4621     }
4624 (define_expand "copysign<mode>3"
4625   [(set (match_dup 3)
4626         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4627    (set (match_dup 4)
4628         (neg:SFDF (abs:SFDF (match_dup 1))))
4629    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4630         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4631                                (match_dup 5))
4632                          (match_dup 3)
4633                          (match_dup 4)))]
4634   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4635    && ((TARGET_PPC_GFXOPT
4636         && !HONOR_NANS (<MODE>mode)
4637         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4638        || TARGET_CMPB
4639        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4641   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4642     {
4643       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4644                                              operands[2]));
4645       DONE;
4646     }
4648    operands[3] = gen_reg_rtx (<MODE>mode);
4649    operands[4] = gen_reg_rtx (<MODE>mode);
4650    operands[5] = CONST0_RTX (<MODE>mode);
4651   })
4653 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4654 ;; and load.
4655 (define_insn_and_split "signbit<mode>2_dm"
4656   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4657         (unspec:SI
4658          [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4659          UNSPEC_SIGNBIT))]
4660   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4661   "#"
4662   "&& reload_completed"
4663   [(const_int 0)]
4665   rs6000_split_signbit (operands[0], operands[1]);
4666   DONE;
4668  [(set_attr "length" "8,8,12")
4669   (set_attr "type" "mftgpr,load,integer")])
4671 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4672 ;; point types, which makes normal SUBREG's problematical. Instead use a
4673 ;; special pattern to avoid using a normal movdi.
4674 (define_insn "signbit<mode>2_dm2"
4675   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4676         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4677                     (const_int 0)]
4678                    UNSPEC_SIGNBIT))]
4679   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4680   "mfvsrd %0,%x1"
4681  [(set_attr "type" "mftgpr")])
4684 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4685 ;; compiler from optimizing -0.0
4686 (define_insn "copysign<mode>3_fcpsgn"
4687   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4688         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4689                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4690                      UNSPEC_COPYSIGN))]
4691   "TARGET_<MODE>_FPR && TARGET_CMPB"
4692   "@
4693    fcpsgn %0,%2,%1
4694    xscpsgndp %x0,%x2,%x1"
4695   [(set_attr "type" "fpsimple")])
4697 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4698 ;; fsel instruction and some auxiliary computations.  Then we just have a
4699 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4700 ;; combine.
4701 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4702 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4703 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4704 ;; define_splits to make them if made by combine.  On VSX machines we have the
4705 ;; min/max instructions.
4707 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4708 ;; to allow either DF/SF to use only traditional registers.
4710 (define_expand "s<minmax><mode>3"
4711   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4712         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4713                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4714   "TARGET_MINMAX_<MODE>"
4716   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4717   DONE;
4720 (define_insn "*s<minmax><mode>3_vsx"
4721   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4722         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4723                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4724   "TARGET_VSX && TARGET_<MODE>_FPR"
4726   return (TARGET_P9_MINMAX
4727           ? "xs<minmax>cdp %x0,%x1,%x2"
4728           : "xs<minmax>dp %x0,%x1,%x2");
4730   [(set_attr "type" "fp")])
4732 ;; The conditional move instructions allow us to perform max and min operations
4733 ;; even when we don't have the appropriate max/min instruction using the FSEL
4734 ;; instruction.
4736 (define_insn_and_split "*s<minmax><mode>3_fpr"
4737   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4738         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4739                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4740   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4741   "#"
4742   "&& 1"
4743   [(const_int 0)]
4745   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4746   DONE;
4749 (define_expand "mov<mode>cc"
4750    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4751          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4752                            (match_operand:GPR 2 "gpc_reg_operand" "")
4753                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4754   "TARGET_ISEL<sel>"
4755   "
4757   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4758     DONE;
4759   else
4760     FAIL;
4763 ;; We use the BASE_REGS for the isel input operands because, if rA is
4764 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4765 ;; because we may switch the operands and rB may end up being rA.
4767 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4768 ;; leave out the mode in operand 4 and use one pattern, but reload can
4769 ;; change the mode underneath our feet and then gets confused trying
4770 ;; to reload the value.
4771 (define_insn "isel_signed_<mode>"
4772   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4773         (if_then_else:GPR
4774          (match_operator 1 "scc_comparison_operator"
4775                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4776                           (const_int 0)])
4777          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4778          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4779   "TARGET_ISEL<sel>"
4780   "*
4781 { return output_isel (operands); }"
4782   [(set_attr "type" "isel")
4783    (set_attr "length" "4")])
4785 (define_insn "isel_unsigned_<mode>"
4786   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4787         (if_then_else:GPR
4788          (match_operator 1 "scc_comparison_operator"
4789                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4790                           (const_int 0)])
4791          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4792          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4793   "TARGET_ISEL<sel>"
4794   "*
4795 { return output_isel (operands); }"
4796   [(set_attr "type" "isel")
4797    (set_attr "length" "4")])
4799 ;; These patterns can be useful for combine; they let combine know that
4800 ;; isel can handle reversed comparisons so long as the operands are
4801 ;; registers.
4803 (define_insn "*isel_reversed_signed_<mode>"
4804   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4805         (if_then_else:GPR
4806          (match_operator 1 "scc_rev_comparison_operator"
4807                          [(match_operand:CC 4 "cc_reg_operand" "y")
4808                           (const_int 0)])
4809          (match_operand:GPR 2 "gpc_reg_operand" "b")
4810          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4811   "TARGET_ISEL<sel>"
4812   "*
4813 { return output_isel (operands); }"
4814   [(set_attr "type" "isel")
4815    (set_attr "length" "4")])
4817 (define_insn "*isel_reversed_unsigned_<mode>"
4818   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4819         (if_then_else:GPR
4820          (match_operator 1 "scc_rev_comparison_operator"
4821                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4822                           (const_int 0)])
4823          (match_operand:GPR 2 "gpc_reg_operand" "b")
4824          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4825   "TARGET_ISEL<sel>"
4826   "*
4827 { return output_isel (operands); }"
4828   [(set_attr "type" "isel")
4829    (set_attr "length" "4")])
4831 ;; Floating point conditional move
4832 (define_expand "mov<mode>cc"
4833    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4834          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4835                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4836                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4837   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4838   "
4840   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4841     DONE;
4842   else
4843     FAIL;
4846 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4847   [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4848         (if_then_else:SFDF
4849          (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4850              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4851          (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4852          (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4853   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4854   "fsel %0,%1,%2,%3"
4855   [(set_attr "type" "fp")])
4857 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4858   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4859         (if_then_else:SFDF
4860          (match_operator:CCFP 1 "fpmask_comparison_operator"
4861                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4862                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4863          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4864          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4865    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4866   "TARGET_P9_MINMAX"
4867   "#"
4868   ""
4869   [(set (match_dup 6)
4870         (if_then_else:V2DI (match_dup 1)
4871                            (match_dup 7)
4872                            (match_dup 8)))
4873    (set (match_dup 0)
4874         (if_then_else:SFDF (ne (match_dup 6)
4875                                (match_dup 8))
4876                            (match_dup 4)
4877                            (match_dup 5)))]
4879   if (GET_CODE (operands[6]) == SCRATCH)
4880     operands[6] = gen_reg_rtx (V2DImode);
4882   operands[7] = CONSTM1_RTX (V2DImode);
4883   operands[8] = CONST0_RTX (V2DImode);
4885  [(set_attr "length" "8")
4886   (set_attr "type" "vecperm")])
4888 ;; Handle inverting the fpmask comparisons.
4889 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4890   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4891         (if_then_else:SFDF
4892          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4893                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4894                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4895          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4896          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4897    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4898   "TARGET_P9_MINMAX"
4899   "#"
4900   "&& 1"
4901   [(set (match_dup 6)
4902         (if_then_else:V2DI (match_dup 9)
4903                            (match_dup 7)
4904                            (match_dup 8)))
4905    (set (match_dup 0)
4906         (if_then_else:SFDF (ne (match_dup 6)
4907                                (match_dup 8))
4908                            (match_dup 5)
4909                            (match_dup 4)))]
4911   rtx op1 = operands[1];
4912   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
4914   if (GET_CODE (operands[6]) == SCRATCH)
4915     operands[6] = gen_reg_rtx (V2DImode);
4917   operands[7] = CONSTM1_RTX (V2DImode);
4918   operands[8] = CONST0_RTX (V2DImode);
4920   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
4922  [(set_attr "length" "8")
4923   (set_attr "type" "vecperm")])
4925 (define_insn "*fpmask<mode>"
4926   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4927         (if_then_else:V2DI
4928          (match_operator:CCFP 1 "fpmask_comparison_operator"
4929                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4930                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4931          (match_operand:V2DI 4 "all_ones_constant" "")
4932          (match_operand:V2DI 5 "zero_constant" "")))]
4933   "TARGET_P9_MINMAX"
4934   "xscmp%V1dp %x0,%x2,%x3"
4935   [(set_attr "type" "fpcompare")])
4937 (define_insn "*xxsel<mode>"
4938   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4939         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4940                                (match_operand:V2DI 2 "zero_constant" ""))
4941                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4942                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4943   "TARGET_P9_MINMAX"
4944   "xxsel %x0,%x4,%x3,%x1"
4945   [(set_attr "type" "vecmove")])
4948 ;; Conversions to and from floating-point.
4950 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4951 ; don't want to support putting SImode in FPR registers.
4952 (define_insn "lfiwax"
4953   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
4954         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
4955                    UNSPEC_LFIWAX))]
4956   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4957   "@
4958    lfiwax %0,%y1
4959    lxsiwax %x0,%y1
4960    mtvsrwa %x0,%1
4961    vextsw2d %0,%1"
4962   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
4964 ; This split must be run before register allocation because it allocates the
4965 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4966 ; it earlier to allow for the combiner to merge insns together where it might
4967 ; not be needed and also in case the insns are deleted as dead code.
4969 (define_insn_and_split "floatsi<mode>2_lfiwax"
4970   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4971         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4972    (clobber (match_scratch:DI 2 "=wi"))]
4973   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4974    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4975   "#"
4976   ""
4977   [(pc)]
4978   "
4980   rtx dest = operands[0];
4981   rtx src = operands[1];
4982   rtx tmp;
4984   if (!MEM_P (src) && TARGET_POWERPC64
4985       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4986     tmp = convert_to_mode (DImode, src, false);
4987   else
4988     {
4989       tmp = operands[2];
4990       if (GET_CODE (tmp) == SCRATCH)
4991         tmp = gen_reg_rtx (DImode);
4992       if (MEM_P (src))
4993         {
4994           src = rs6000_address_for_fpconvert (src);
4995           emit_insn (gen_lfiwax (tmp, src));
4996         }
4997       else
4998         {
4999           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5000           emit_move_insn (stack, src);
5001           emit_insn (gen_lfiwax (tmp, stack));
5002         }
5003     }
5004   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5005   DONE;
5007   [(set_attr "length" "12")
5008    (set_attr "type" "fpload")])
5010 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5011   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5012         (float:SFDF
5013          (sign_extend:DI
5014           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5015    (clobber (match_scratch:DI 2 "=wi"))]
5016   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5017    && <SI_CONVERT_FP>"
5018   "#"
5019   ""
5020   [(pc)]
5021   "
5023   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5024   if (GET_CODE (operands[2]) == SCRATCH)
5025     operands[2] = gen_reg_rtx (DImode);
5026   if (TARGET_VSX_SMALL_INTEGER)
5027     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5028   else
5029     emit_insn (gen_lfiwax (operands[2], operands[1]));
5030   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5031   DONE;
5033   [(set_attr "length" "8")
5034    (set_attr "type" "fpload")])
5036 (define_insn "lfiwzx"
5037   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5038         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5039                    UNSPEC_LFIWZX))]
5040   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5041   "@
5042    lfiwzx %0,%y1
5043    lxsiwzx %x0,%y1
5044    mtvsrwz %x0,%1
5045    xxextractuw %x0,%x1,1"
5046   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5048 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5049   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5050         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5051    (clobber (match_scratch:DI 2 "=wi"))]
5052   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5053    && <SI_CONVERT_FP>"
5054   "#"
5055   ""
5056   [(pc)]
5057   "
5059   rtx dest = operands[0];
5060   rtx src = operands[1];
5061   rtx tmp;
5063   if (!MEM_P (src) && TARGET_POWERPC64
5064       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5065     tmp = convert_to_mode (DImode, src, true);
5066   else
5067     {
5068       tmp = operands[2];
5069       if (GET_CODE (tmp) == SCRATCH)
5070         tmp = gen_reg_rtx (DImode);
5071       if (MEM_P (src))
5072         {
5073           src = rs6000_address_for_fpconvert (src);
5074           emit_insn (gen_lfiwzx (tmp, src));
5075         }
5076       else
5077         {
5078           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5079           emit_move_insn (stack, src);
5080           emit_insn (gen_lfiwzx (tmp, stack));
5081         }
5082     }
5083   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5084   DONE;
5086   [(set_attr "length" "12")
5087    (set_attr "type" "fpload")])
5089 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5090   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5091         (unsigned_float:SFDF
5092          (zero_extend:DI
5093           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5094    (clobber (match_scratch:DI 2 "=wi"))]
5095   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5096    && <SI_CONVERT_FP>"
5097   "#"
5098   ""
5099   [(pc)]
5100   "
5102   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5103   if (GET_CODE (operands[2]) == SCRATCH)
5104     operands[2] = gen_reg_rtx (DImode);
5105   if (TARGET_VSX_SMALL_INTEGER)
5106     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5107   else
5108     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5109   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5110   DONE;
5112   [(set_attr "length" "8")
5113    (set_attr "type" "fpload")])
5115 ; For each of these conversions, there is a define_expand, a define_insn
5116 ; with a '#' template, and a define_split (with C code).  The idea is
5117 ; to allow constant folding with the template of the define_insn,
5118 ; then to have the insns split later (between sched1 and final).
5120 (define_expand "floatsidf2"
5121   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5122                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5123               (use (match_dup 2))
5124               (use (match_dup 3))
5125               (clobber (match_dup 4))
5126               (clobber (match_dup 5))
5127               (clobber (match_dup 6))])]
5128   "TARGET_HARD_FLOAT 
5129    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5130   "
5132   if (TARGET_E500_DOUBLE)
5133     {
5134       if (!REG_P (operands[1]))
5135         operands[1] = force_reg (SImode, operands[1]);
5136       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5137       DONE;
5138     }
5139   else if (TARGET_LFIWAX && TARGET_FCFID)
5140     {
5141       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5142       DONE;
5143     }
5144   else if (TARGET_FCFID)
5145     {
5146       rtx dreg = operands[1];
5147       if (!REG_P (dreg))
5148         dreg = force_reg (SImode, dreg);
5149       dreg = convert_to_mode (DImode, dreg, false);
5150       emit_insn (gen_floatdidf2 (operands[0], dreg));
5151       DONE;
5152     }
5154   if (!REG_P (operands[1]))
5155     operands[1] = force_reg (SImode, operands[1]);
5156   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5157   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5158   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5159   operands[5] = gen_reg_rtx (DFmode);
5160   operands[6] = gen_reg_rtx (SImode);
5163 (define_insn_and_split "*floatsidf2_internal"
5164   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5165         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5166    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5167    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5168    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5169    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5170    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5171   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5172   "#"
5173   ""
5174   [(pc)]
5175   "
5177   rtx lowword, highword;
5178   gcc_assert (MEM_P (operands[4]));
5179   highword = adjust_address (operands[4], SImode, 0);
5180   lowword = adjust_address (operands[4], SImode, 4);
5181   if (! WORDS_BIG_ENDIAN)
5182     std::swap (lowword, highword);
5184   emit_insn (gen_xorsi3 (operands[6], operands[1],
5185                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5186   emit_move_insn (lowword, operands[6]);
5187   emit_move_insn (highword, operands[2]);
5188   emit_move_insn (operands[5], operands[4]);
5189   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5190   DONE;
5192   [(set_attr "length" "24")
5193    (set_attr "type" "fp")])
5195 ;; If we don't have a direct conversion to single precision, don't enable this
5196 ;; conversion for 32-bit without fast math, because we don't have the insn to
5197 ;; generate the fixup swizzle to avoid double rounding problems.
5198 (define_expand "floatunssisf2"
5199   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5200         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5201   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5202    && (!TARGET_FPRS
5203        || (TARGET_FPRS
5204            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5205                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5206                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5207   "
5209   if (!TARGET_FPRS)
5210     {
5211       if (!REG_P (operands[1]))
5212         operands[1] = force_reg (SImode, operands[1]);
5213     }
5214   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5215     {
5216       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5217       DONE;
5218     }
5219   else
5220     {
5221       rtx dreg = operands[1];
5222       if (!REG_P (dreg))
5223         dreg = force_reg (SImode, dreg);
5224       dreg = convert_to_mode (DImode, dreg, true);
5225       emit_insn (gen_floatdisf2 (operands[0], dreg));
5226       DONE;
5227     }
5230 (define_expand "floatunssidf2"
5231   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5232                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5233               (use (match_dup 2))
5234               (use (match_dup 3))
5235               (clobber (match_dup 4))
5236               (clobber (match_dup 5))])]
5237   "TARGET_HARD_FLOAT
5238    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5239   "
5241   if (TARGET_E500_DOUBLE)
5242     {
5243       if (!REG_P (operands[1]))
5244         operands[1] = force_reg (SImode, operands[1]);
5245       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5246       DONE;
5247     }
5248   else if (TARGET_LFIWZX && TARGET_FCFID)
5249     {
5250       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5251       DONE;
5252     }
5253   else if (TARGET_FCFID)
5254     {
5255       rtx dreg = operands[1];
5256       if (!REG_P (dreg))
5257         dreg = force_reg (SImode, dreg);
5258       dreg = convert_to_mode (DImode, dreg, true);
5259       emit_insn (gen_floatdidf2 (operands[0], dreg));
5260       DONE;
5261     }
5263   if (!REG_P (operands[1]))
5264     operands[1] = force_reg (SImode, operands[1]);
5265   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5266   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5267   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5268   operands[5] = gen_reg_rtx (DFmode);
5271 (define_insn_and_split "*floatunssidf2_internal"
5272   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5273         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5274    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5275    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5276    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5277    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5278   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5279    && !(TARGET_FCFID && TARGET_POWERPC64)"
5280   "#"
5281   ""
5282   [(pc)]
5283   "
5285   rtx lowword, highword;
5286   gcc_assert (MEM_P (operands[4]));
5287   highword = adjust_address (operands[4], SImode, 0);
5288   lowword = adjust_address (operands[4], SImode, 4);
5289   if (! WORDS_BIG_ENDIAN)
5290     std::swap (lowword, highword);
5292   emit_move_insn (lowword, operands[1]);
5293   emit_move_insn (highword, operands[2]);
5294   emit_move_insn (operands[5], operands[4]);
5295   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5296   DONE;
5298   [(set_attr "length" "20")
5299    (set_attr "type" "fp")])
5301 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5302 ;; vector registers.  At the moment, QI/HImode are not allowed in floating
5303 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5304 ;; half-word instructions.
5306 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5307   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5308                    (float:FP_ISA3
5309                     (match_operand:QHI 1 "input_operand")))
5310               (clobber (match_scratch:DI 2))
5311               (clobber (match_scratch:DI 3))])]
5312   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5314   if (MEM_P (operands[1]))
5315     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5318 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5319   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5320         (float:FP_ISA3
5321          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5322    (clobber (match_scratch:DI 2 "=wi,v"))
5323    (clobber (match_scratch:DI 3 "=r,X"))]
5324   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5325    && TARGET_UPPER_REGS_DI"
5326   "#"
5327   "&& reload_completed"
5328   [(const_int 0)]
5330   rtx result = operands[0];
5331   rtx input = operands[1];
5332   rtx di = operands[2];
5334   if (!MEM_P (input))
5335     {
5336       rtx tmp = operands[3];
5337       emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5338       emit_move_insn (di, tmp);
5339     }
5340   else
5341     {
5342       machine_mode vmode;
5343       rtx di_vector;
5345       emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5347       if (<MODE>mode == QImode)
5348         vmode = V16QImode;
5349       else if (<MODE>mode == HImode)
5350         vmode = V8HImode;
5351       else
5352         gcc_unreachable ();
5354       di_vector = gen_rtx_REG (vmode, REGNO (di));
5355       emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5356     }
5358   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5359   DONE;
5362 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5363   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5364                    (unsigned_float:FP_ISA3
5365                     (match_operand:QHI 1 "input_operand" "")))
5366               (clobber (match_scratch:DI 2 ""))
5367               (clobber (match_scratch:DI 3 ""))])]
5368   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5370   if (MEM_P (operands[1]))
5371     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5374 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5375   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5376         (unsigned_float:FP_ISA3
5377          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5378    (clobber (match_scratch:DI 2 "=wi,wi"))
5379    (clobber (match_scratch:DI 3 "=r,X"))]
5380   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5381   "#"
5382   "&& reload_completed"
5383   [(const_int 0)]
5385   rtx result = operands[0];
5386   rtx input = operands[1];
5387   rtx di = operands[2];
5388   rtx tmp = operands[3];
5390   if (!MEM_P (input))
5391     {
5392       emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5393       emit_move_insn (di, tmp);
5394     }
5395   else
5396     emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5398   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5399   DONE;
5402 (define_expand "fix_trunc<mode>si2"
5403   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5404         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5405   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5406   "
5408   if (!<E500_CONVERT>)
5409     {
5410       rtx src = force_reg (<MODE>mode, operands[1]);
5412       if (TARGET_STFIWX)
5413         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5414       else
5415         {
5416           rtx tmp = gen_reg_rtx (DImode);
5417           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5418           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5419                                                       tmp, stack));
5420         }
5421       DONE;
5422     }
5425 ; Like the convert to float patterns, this insn must be split before
5426 ; register allocation so that it can allocate the memory slot if it
5427 ; needed
5428 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5429   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5430         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5431    (clobber (match_scratch:DI 2 "=d"))]
5432   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5433    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5434    && TARGET_STFIWX && can_create_pseudo_p ()"
5435   "#"
5436   ""
5437   [(pc)]
5439   rtx dest = operands[0];
5440   rtx src = operands[1];
5441   rtx tmp = operands[2];
5443   if (GET_CODE (tmp) == SCRATCH)
5444     tmp = gen_reg_rtx (DImode);
5446   emit_insn (gen_fctiwz_<mode> (tmp, src));
5447   if (MEM_P (dest))
5448     {
5449       dest = rs6000_address_for_fpconvert (dest);
5450       emit_insn (gen_stfiwx (dest, tmp));
5451       DONE;
5452     }
5453   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5454     {
5455       dest = gen_lowpart (DImode, dest);
5456       emit_move_insn (dest, tmp);
5457       DONE;
5458     }
5459   else
5460     {
5461       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5462       emit_insn (gen_stfiwx (stack, tmp));
5463       emit_move_insn (dest, stack);
5464       DONE;
5465     }
5467   [(set_attr "length" "12")
5468    (set_attr "type" "fp")])
5470 (define_insn_and_split "fix_trunc<mode>si2_internal"
5471   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5472         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5473    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5474    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5475   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5476   "#"
5477   ""
5478   [(pc)]
5479   "
5481   rtx lowword;
5482   gcc_assert (MEM_P (operands[3]));
5483   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5485   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5486   emit_move_insn (operands[3], operands[2]);
5487   emit_move_insn (operands[0], lowword);
5488   DONE;
5490   [(set_attr "length" "16")
5491    (set_attr "type" "fp")])
5493 (define_expand "fix_trunc<mode>di2"
5494   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5495         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5496   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5497    && TARGET_FCFID"
5498   "")
5500 (define_insn "*fix_trunc<mode>di2_fctidz"
5501   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5502         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5503   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5504     && TARGET_FCFID"
5505   "@
5506    fctidz %0,%1
5507    xscvdpsxds %x0,%x1"
5508   [(set_attr "type" "fp")])
5510 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5511   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5512    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5513   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5515   rtx op0 = operands[0];
5516   rtx op1 = operands[1];
5517   rtx di_tmp = gen_reg_rtx (DImode);
5519   if (MEM_P (op0))
5520     op0 = rs6000_address_for_fpconvert (op0);
5522   emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5523   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5524   DONE;
5527 (define_expand "fixuns_trunc<mode>si2"
5528   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5529         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5530   "TARGET_HARD_FLOAT
5531    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5532        || <E500_CONVERT>)"
5533   "
5535   if (!<E500_CONVERT>)
5536     {
5537       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5538       DONE;
5539     }
5542 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5543   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5544         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5545    (clobber (match_scratch:DI 2 "=d"))]
5546   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5547    && TARGET_STFIWX && can_create_pseudo_p ()"
5548   "#"
5549   ""
5550   [(pc)]
5552   rtx dest = operands[0];
5553   rtx src = operands[1];
5554   rtx tmp = operands[2];
5556   if (GET_CODE (tmp) == SCRATCH)
5557     tmp = gen_reg_rtx (DImode);
5559   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5560   if (MEM_P (dest))
5561     {
5562       dest = rs6000_address_for_fpconvert (dest);
5563       emit_insn (gen_stfiwx (dest, tmp));
5564       DONE;
5565     }
5566   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5567     {
5568       dest = gen_lowpart (DImode, dest);
5569       emit_move_insn (dest, tmp);
5570       DONE;
5571     }
5572   else
5573     {
5574       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5575       emit_insn (gen_stfiwx (stack, tmp));
5576       emit_move_insn (dest, stack);
5577       DONE;
5578     }
5580   [(set_attr "length" "12")
5581    (set_attr "type" "fp")])
5583 (define_expand "fixuns_trunc<mode>di2"
5584   [(set (match_operand:DI 0 "register_operand" "")
5585         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5586   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5587   "")
5589 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5590   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5591         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5592   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5593     && TARGET_FCTIDUZ"
5594   "@
5595    fctiduz %0,%1
5596    xscvdpuxds %x0,%x1"
5597   [(set_attr "type" "fp")])
5599 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5600   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5601    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5602   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5604   rtx op0 = operands[0];
5605   rtx op1 = operands[1];
5606   rtx di_tmp = gen_reg_rtx (DImode);
5608   if (MEM_P (op0))
5609     op0 = rs6000_address_for_fpconvert (op0);
5611   emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5612   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5613   DONE;
5616 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5617 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5618 ; because the first makes it clear that operand 0 is not live
5619 ; before the instruction.
5620 (define_insn "fctiwz_<mode>"
5621   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5622         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5623                    UNSPEC_FCTIWZ))]
5624   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5625   "@
5626    fctiwz %0,%1
5627    xscvdpsxws %x0,%x1"
5628   [(set_attr "type" "fp")])
5630 (define_insn "fctiwuz_<mode>"
5631   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5632         (unspec:DI [(unsigned_fix:SI
5633                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5634                    UNSPEC_FCTIWUZ))]
5635   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5636   "@
5637    fctiwuz %0,%1
5638    xscvdpuxws %x0,%x1"
5639   [(set_attr "type" "fp")])
5641 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5642 ;; since the friz instruction does not truncate the value if the floating
5643 ;; point value is < LONG_MIN or > LONG_MAX.
5644 (define_insn "*friz"
5645   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5646         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5647   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5648    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5649   "@
5650    friz %0,%1
5651    xsrdpiz %x0,%x1"
5652   [(set_attr "type" "fp")])
5654 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5655 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5656 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5657 ;; extend it, store it back on the stack from the GPR, load it back into the
5658 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5659 ;; disable using store and load to sign/zero extend the value.
5660 (define_insn_and_split "*round32<mode>2_fprs"
5661   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5662         (float:SFDF
5663          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5664    (clobber (match_scratch:DI 2 "=d"))
5665    (clobber (match_scratch:DI 3 "=d"))]
5666   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5667    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5668    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5669   "#"
5670   ""
5671   [(pc)]
5673   rtx dest = operands[0];
5674   rtx src = operands[1];
5675   rtx tmp1 = operands[2];
5676   rtx tmp2 = operands[3];
5677   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5679   if (GET_CODE (tmp1) == SCRATCH)
5680     tmp1 = gen_reg_rtx (DImode);
5681   if (GET_CODE (tmp2) == SCRATCH)
5682     tmp2 = gen_reg_rtx (DImode);
5684   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5685   emit_insn (gen_stfiwx (stack, tmp1));
5686   emit_insn (gen_lfiwax (tmp2, stack));
5687   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5688   DONE;
5690   [(set_attr "type" "fpload")
5691    (set_attr "length" "16")])
5693 (define_insn_and_split "*roundu32<mode>2_fprs"
5694   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5695         (unsigned_float:SFDF
5696          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5697    (clobber (match_scratch:DI 2 "=d"))
5698    (clobber (match_scratch:DI 3 "=d"))]
5699   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5700    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5701    && can_create_pseudo_p ()"
5702   "#"
5703   ""
5704   [(pc)]
5706   rtx dest = operands[0];
5707   rtx src = operands[1];
5708   rtx tmp1 = operands[2];
5709   rtx tmp2 = operands[3];
5710   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5712   if (GET_CODE (tmp1) == SCRATCH)
5713     tmp1 = gen_reg_rtx (DImode);
5714   if (GET_CODE (tmp2) == SCRATCH)
5715     tmp2 = gen_reg_rtx (DImode);
5717   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5718   emit_insn (gen_stfiwx (stack, tmp1));
5719   emit_insn (gen_lfiwzx (tmp2, stack));
5720   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5721   DONE;
5723   [(set_attr "type" "fpload")
5724    (set_attr "length" "16")])
5726 ;; No VSX equivalent to fctid
5727 (define_insn "lrint<mode>di2"
5728   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5729         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5730                    UNSPEC_FCTID))]
5731   "TARGET_<MODE>_FPR && TARGET_FPRND"
5732   "fctid %0,%1"
5733   [(set_attr "type" "fp")])
5735 (define_insn "btrunc<mode>2"
5736   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5737         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5738                      UNSPEC_FRIZ))]
5739   "TARGET_<MODE>_FPR && TARGET_FPRND"
5740   "@
5741    friz %0,%1
5742    xsrdpiz %x0,%x1"
5743   [(set_attr "type" "fp")
5744    (set_attr "fp_type" "fp_addsub_<Fs>")])
5746 (define_insn "ceil<mode>2"
5747   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5748         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5749                      UNSPEC_FRIP))]
5750   "TARGET_<MODE>_FPR && TARGET_FPRND"
5751   "@
5752    frip %0,%1
5753    xsrdpip %x0,%x1"
5754   [(set_attr "type" "fp")
5755    (set_attr "fp_type" "fp_addsub_<Fs>")])
5757 (define_insn "floor<mode>2"
5758   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5759         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5760                      UNSPEC_FRIM))]
5761   "TARGET_<MODE>_FPR && TARGET_FPRND"
5762   "@
5763    frim %0,%1
5764    xsrdpim %x0,%x1"
5765   [(set_attr "type" "fp")
5766    (set_attr "fp_type" "fp_addsub_<Fs>")])
5768 ;; No VSX equivalent to frin
5769 (define_insn "round<mode>2"
5770   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5771         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5772                      UNSPEC_FRIN))]
5773   "TARGET_<MODE>_FPR && TARGET_FPRND"
5774   "frin %0,%1"
5775   [(set_attr "type" "fp")
5776    (set_attr "fp_type" "fp_addsub_<Fs>")])
5778 (define_insn "*xsrdpi<mode>2"
5779   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5780         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5781                      UNSPEC_XSRDPI))]
5782   "TARGET_<MODE>_FPR && TARGET_VSX"
5783   "xsrdpi %x0,%x1"
5784   [(set_attr "type" "fp")
5785    (set_attr "fp_type" "fp_addsub_<Fs>")])
5787 (define_expand "lround<mode>di2"
5788   [(set (match_dup 2)
5789         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5790                      UNSPEC_XSRDPI))
5791    (set (match_operand:DI 0 "gpc_reg_operand" "")
5792         (unspec:DI [(match_dup 2)]
5793                    UNSPEC_FCTID))]
5794   "TARGET_<MODE>_FPR && TARGET_VSX"
5796   operands[2] = gen_reg_rtx (<MODE>mode);
5799 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5800 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5801 ; is only generated for Power8 or later.
5802 (define_insn "stfiwx"
5803   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5804         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5805                    UNSPEC_STFIWX))]
5806   "TARGET_PPC_GFXOPT"
5807   "@
5808    stfiwx %1,%y0
5809    stxsiwx %x1,%y0"
5810   [(set_attr "type" "fpstore")])
5812 ;; If we don't have a direct conversion to single precision, don't enable this
5813 ;; conversion for 32-bit without fast math, because we don't have the insn to
5814 ;; generate the fixup swizzle to avoid double rounding problems.
5815 (define_expand "floatsisf2"
5816   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5817         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5818   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5819    && (!TARGET_FPRS
5820        || (TARGET_FPRS
5821            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5822                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5823                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5824   "
5826   if (!TARGET_FPRS)
5827     {
5828       if (!REG_P (operands[1]))
5829         operands[1] = force_reg (SImode, operands[1]);
5830     }
5831   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5832     {
5833       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5834       DONE;
5835     }
5836   else if (TARGET_FCFID && TARGET_LFIWAX)
5837     {
5838       rtx dfreg = gen_reg_rtx (DFmode);
5839       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5840       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5841       DONE;
5842     }
5843   else
5844     {
5845       rtx dreg = operands[1];
5846       if (!REG_P (dreg))
5847         dreg = force_reg (SImode, dreg);
5848       dreg = convert_to_mode (DImode, dreg, false);
5849       emit_insn (gen_floatdisf2 (operands[0], dreg));
5850       DONE;
5851     }
5854 (define_expand "floatdidf2"
5855   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5856         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5857   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5858   "")
5860 (define_insn "*floatdidf2_fpr"
5861   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5862         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5863   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5864   "@
5865    fcfid %0,%1
5866    xscvsxddp %x0,%x1"
5867   [(set_attr "type" "fp")])
5869 ; Allow the combiner to merge source memory operands to the conversion so that
5870 ; the optimizer/register allocator doesn't try to load the value too early in a
5871 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5872 ; hit.  We will split after reload to avoid the trip through the GPRs
5874 (define_insn_and_split "*floatdidf2_mem"
5875   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5876         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5877    (clobber (match_scratch:DI 2 "=d,wi"))]
5878   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5879   "#"
5880   "&& reload_completed"
5881   [(set (match_dup 2) (match_dup 1))
5882    (set (match_dup 0) (float:DF (match_dup 2)))]
5883   ""
5884   [(set_attr "length" "8")
5885    (set_attr "type" "fpload")])
5887 (define_expand "floatunsdidf2"
5888   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5889         (unsigned_float:DF
5890          (match_operand:DI 1 "gpc_reg_operand" "")))]
5891   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5892   "")
5894 (define_insn "*floatunsdidf2_fcfidu"
5895   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5896         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5897   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5898   "@
5899    fcfidu %0,%1
5900    xscvuxddp %x0,%x1"
5901   [(set_attr "type" "fp")
5902    (set_attr "length" "4")])
5904 (define_insn_and_split "*floatunsdidf2_mem"
5905   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5906         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5907    (clobber (match_scratch:DI 2 "=d,wi"))]
5908   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5909   "#"
5910   "&& reload_completed"
5911   [(set (match_dup 2) (match_dup 1))
5912    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5913   ""
5914   [(set_attr "length" "8")
5915    (set_attr "type" "fpload")])
5917 (define_expand "floatdisf2"
5918   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5919         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5920   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5921    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5922   "
5924   if (!TARGET_FCFIDS)
5925     {
5926       rtx val = operands[1];
5927       if (!flag_unsafe_math_optimizations)
5928         {
5929           rtx label = gen_label_rtx ();
5930           val = gen_reg_rtx (DImode);
5931           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5932           emit_label (label);
5933         }
5934       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5935       DONE;
5936     }
5939 (define_insn "floatdisf2_fcfids"
5940   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5941         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5942   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5943    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5944   "@
5945    fcfids %0,%1
5946    xscvsxdsp %x0,%x1"
5947   [(set_attr "type" "fp")])
5949 (define_insn_and_split "*floatdisf2_mem"
5950   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5951         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5952    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5953   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5954    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5955   "#"
5956   "&& reload_completed"
5957   [(pc)]
5958   "
5960   emit_move_insn (operands[2], operands[1]);
5961   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5962   DONE;
5964   [(set_attr "length" "8")])
5966 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5967 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5968 ;; from double rounding.
5969 ;; Instead of creating a new cpu type for two FP operations, just use fp
5970 (define_insn_and_split "floatdisf2_internal1"
5971   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5972         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5973    (clobber (match_scratch:DF 2 "=d"))]
5974   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5975    && !TARGET_FCFIDS"
5976   "#"
5977   "&& reload_completed"
5978   [(set (match_dup 2)
5979         (float:DF (match_dup 1)))
5980    (set (match_dup 0)
5981         (float_truncate:SF (match_dup 2)))]
5982   ""
5983   [(set_attr "length" "8")
5984    (set_attr "type" "fp")])
5986 ;; Twiddles bits to avoid double rounding.
5987 ;; Bits that might be truncated when converting to DFmode are replaced
5988 ;; by a bit that won't be lost at that stage, but is below the SFmode
5989 ;; rounding position.
5990 (define_expand "floatdisf2_internal2"
5991   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5992                                               (const_int 53)))
5993               (clobber (reg:DI CA_REGNO))])
5994    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5995                                            (const_int 2047)))
5996    (set (match_dup 3) (plus:DI (match_dup 3)
5997                                (const_int 1)))
5998    (set (match_dup 0) (plus:DI (match_dup 0)
5999                                (const_int 2047)))
6000    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6001                                      (const_int 2)))
6002    (set (match_dup 0) (ior:DI (match_dup 0)
6003                               (match_dup 1)))
6004    (set (match_dup 0) (and:DI (match_dup 0)
6005                               (const_int -2048)))
6006    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6007                            (label_ref (match_operand:DI 2 "" ""))
6008                            (pc)))
6009    (set (match_dup 0) (match_dup 1))]
6010   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6011    && !TARGET_FCFIDS"
6012   "
6014   operands[3] = gen_reg_rtx (DImode);
6015   operands[4] = gen_reg_rtx (CCUNSmode);
6018 (define_expand "floatunsdisf2"
6019   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6020         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6021   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6022    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6023   "")
6025 (define_insn "floatunsdisf2_fcfidus"
6026   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6027         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6028   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6029    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6030   "@
6031    fcfidus %0,%1
6032    xscvuxdsp %x0,%x1"
6033   [(set_attr "type" "fp")])
6035 (define_insn_and_split "*floatunsdisf2_mem"
6036   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6037         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6038    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6039   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6040    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6041   "#"
6042   "&& reload_completed"
6043   [(pc)]
6044   "
6046   emit_move_insn (operands[2], operands[1]);
6047   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6048   DONE;
6050   [(set_attr "length" "8")
6051    (set_attr "type" "fpload")])
6053 ;; Define the TImode operations that can be done in a small number
6054 ;; of instructions.  The & constraints are to prevent the register
6055 ;; allocator from allocating registers that overlap with the inputs
6056 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6057 ;; also allow for the output being the same as one of the inputs.
6059 (define_expand "addti3"
6060   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6061         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6062                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6063   "TARGET_64BIT"
6065   rtx lo0 = gen_lowpart (DImode, operands[0]);
6066   rtx lo1 = gen_lowpart (DImode, operands[1]);
6067   rtx lo2 = gen_lowpart (DImode, operands[2]);
6068   rtx hi0 = gen_highpart (DImode, operands[0]);
6069   rtx hi1 = gen_highpart (DImode, operands[1]);
6070   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6072   if (!reg_or_short_operand (lo2, DImode))
6073     lo2 = force_reg (DImode, lo2);
6074   if (!adde_operand (hi2, DImode))
6075     hi2 = force_reg (DImode, hi2);
6077   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6078   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6079   DONE;
6082 (define_expand "subti3"
6083   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6084         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6085                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6086   "TARGET_64BIT"
6088   rtx lo0 = gen_lowpart (DImode, operands[0]);
6089   rtx lo1 = gen_lowpart (DImode, operands[1]);
6090   rtx lo2 = gen_lowpart (DImode, operands[2]);
6091   rtx hi0 = gen_highpart (DImode, operands[0]);
6092   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6093   rtx hi2 = gen_highpart (DImode, operands[2]);
6095   if (!reg_or_short_operand (lo1, DImode))
6096     lo1 = force_reg (DImode, lo1);
6097   if (!adde_operand (hi1, DImode))
6098     hi1 = force_reg (DImode, hi1);
6100   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6101   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6102   DONE;
6105 ;; 128-bit logical operations expanders
6107 (define_expand "and<mode>3"
6108   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6109         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6110                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6111   ""
6112   "")
6114 (define_expand "ior<mode>3"
6115   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6116         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6117                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6118   ""
6119   "")
6121 (define_expand "xor<mode>3"
6122   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6123         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6124                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6125   ""
6126   "")
6128 (define_expand "one_cmpl<mode>2"
6129   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6130         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6131   ""
6132   "")
6134 (define_expand "nor<mode>3"
6135   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6136         (and:BOOL_128
6137          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6138          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6139   ""
6140   "")
6142 (define_expand "andc<mode>3"
6143   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6144         (and:BOOL_128
6145          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6146          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6147   ""
6148   "")
6150 ;; Power8 vector logical instructions.
6151 (define_expand "eqv<mode>3"
6152   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6153         (not:BOOL_128
6154          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6155                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6156   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6157   "")
6159 ;; Rewrite nand into canonical form
6160 (define_expand "nand<mode>3"
6161   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6162         (ior:BOOL_128
6163          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6164          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6165   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6166   "")
6168 ;; The canonical form is to have the negated element first, so we need to
6169 ;; reverse arguments.
6170 (define_expand "orc<mode>3"
6171   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6172         (ior:BOOL_128
6173          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6174          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6175   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6176   "")
6178 ;; 128-bit logical operations insns and split operations
6179 (define_insn_and_split "*and<mode>3_internal"
6180   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6181         (and:BOOL_128
6182          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6183          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6184   ""
6186   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6187     return "xxland %x0,%x1,%x2";
6189   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6190     return "vand %0,%1,%2";
6192   return "#";
6194   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6195   [(const_int 0)]
6197   rs6000_split_logical (operands, AND, false, false, false);
6198   DONE;
6200   [(set (attr "type")
6201       (if_then_else
6202         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6203         (const_string "veclogical")
6204         (const_string "integer")))
6205    (set (attr "length")
6206       (if_then_else
6207         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6208         (const_string "4")
6209         (if_then_else
6210          (match_test "TARGET_POWERPC64")
6211          (const_string "8")
6212          (const_string "16"))))])
6214 ;; 128-bit IOR/XOR
6215 (define_insn_and_split "*bool<mode>3_internal"
6216   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6217         (match_operator:BOOL_128 3 "boolean_or_operator"
6218          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6219           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6220   ""
6222   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6223     return "xxl%q3 %x0,%x1,%x2";
6225   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6226     return "v%q3 %0,%1,%2";
6228   return "#";
6230   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6231   [(const_int 0)]
6233   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6234   DONE;
6236   [(set (attr "type")
6237       (if_then_else
6238         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6239         (const_string "veclogical")
6240         (const_string "integer")))
6241    (set (attr "length")
6242       (if_then_else
6243         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6244         (const_string "4")
6245         (if_then_else
6246          (match_test "TARGET_POWERPC64")
6247          (const_string "8")
6248          (const_string "16"))))])
6250 ;; 128-bit ANDC/ORC
6251 (define_insn_and_split "*boolc<mode>3_internal1"
6252   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6253         (match_operator:BOOL_128 3 "boolean_operator"
6254          [(not:BOOL_128
6255            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6256           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6257   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6259   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6260     return "xxl%q3 %x0,%x1,%x2";
6262   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6263     return "v%q3 %0,%1,%2";
6265   return "#";
6267   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6268    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6269   [(const_int 0)]
6271   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6272   DONE;
6274   [(set (attr "type")
6275       (if_then_else
6276         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6277         (const_string "veclogical")
6278         (const_string "integer")))
6279    (set (attr "length")
6280       (if_then_else
6281         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6282         (const_string "4")
6283         (if_then_else
6284          (match_test "TARGET_POWERPC64")
6285          (const_string "8")
6286          (const_string "16"))))])
6288 (define_insn_and_split "*boolc<mode>3_internal2"
6289   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6290         (match_operator:TI2 3 "boolean_operator"
6291          [(not:TI2
6292            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6293           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6294   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6295   "#"
6296   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6297   [(const_int 0)]
6299   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6300   DONE;
6302   [(set_attr "type" "integer")
6303    (set (attr "length")
6304         (if_then_else
6305          (match_test "TARGET_POWERPC64")
6306          (const_string "8")
6307          (const_string "16")))])
6309 ;; 128-bit NAND/NOR
6310 (define_insn_and_split "*boolcc<mode>3_internal1"
6311   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6312         (match_operator:BOOL_128 3 "boolean_operator"
6313          [(not:BOOL_128
6314            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6315           (not:BOOL_128
6316            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6317   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6319   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6320     return "xxl%q3 %x0,%x1,%x2";
6322   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6323     return "v%q3 %0,%1,%2";
6325   return "#";
6327   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6328    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6329   [(const_int 0)]
6331   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6332   DONE;
6334   [(set (attr "type")
6335       (if_then_else
6336         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6337         (const_string "veclogical")
6338         (const_string "integer")))
6339    (set (attr "length")
6340       (if_then_else
6341         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6342         (const_string "4")
6343         (if_then_else
6344          (match_test "TARGET_POWERPC64")
6345          (const_string "8")
6346          (const_string "16"))))])
6348 (define_insn_and_split "*boolcc<mode>3_internal2"
6349   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6350         (match_operator:TI2 3 "boolean_operator"
6351          [(not:TI2
6352            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6353           (not:TI2
6354            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6355   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6356   "#"
6357   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6358   [(const_int 0)]
6360   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6361   DONE;
6363   [(set_attr "type" "integer")
6364    (set (attr "length")
6365         (if_then_else
6366          (match_test "TARGET_POWERPC64")
6367          (const_string "8")
6368          (const_string "16")))])
6371 ;; 128-bit EQV
6372 (define_insn_and_split "*eqv<mode>3_internal1"
6373   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6374         (not:BOOL_128
6375          (xor:BOOL_128
6376           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6377           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6378   "TARGET_P8_VECTOR"
6380   if (vsx_register_operand (operands[0], <MODE>mode))
6381     return "xxleqv %x0,%x1,%x2";
6383   return "#";
6385   "TARGET_P8_VECTOR && reload_completed
6386    && int_reg_operand (operands[0], <MODE>mode)"
6387   [(const_int 0)]
6389   rs6000_split_logical (operands, XOR, true, false, false);
6390   DONE;
6392   [(set (attr "type")
6393       (if_then_else
6394         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395         (const_string "veclogical")
6396         (const_string "integer")))
6397    (set (attr "length")
6398       (if_then_else
6399         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6400         (const_string "4")
6401         (if_then_else
6402          (match_test "TARGET_POWERPC64")
6403          (const_string "8")
6404          (const_string "16"))))])
6406 (define_insn_and_split "*eqv<mode>3_internal2"
6407   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6408         (not:TI2
6409          (xor:TI2
6410           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6411           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6412   "!TARGET_P8_VECTOR"
6413   "#"
6414   "reload_completed && !TARGET_P8_VECTOR"
6415   [(const_int 0)]
6417   rs6000_split_logical (operands, XOR, true, false, false);
6418   DONE;
6420   [(set_attr "type" "integer")
6421    (set (attr "length")
6422         (if_then_else
6423          (match_test "TARGET_POWERPC64")
6424          (const_string "8")
6425          (const_string "16")))])
6427 ;; 128-bit one's complement
6428 (define_insn_and_split "*one_cmpl<mode>3_internal"
6429   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6430         (not:BOOL_128
6431           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6432   ""
6434   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6435     return "xxlnor %x0,%x1,%x1";
6437   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6438     return "vnor %0,%1,%1";
6440   return "#";
6442   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6443   [(const_int 0)]
6445   rs6000_split_logical (operands, NOT, false, false, false);
6446   DONE;
6448   [(set (attr "type")
6449       (if_then_else
6450         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6451         (const_string "veclogical")
6452         (const_string "integer")))
6453    (set (attr "length")
6454       (if_then_else
6455         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6456         (const_string "4")
6457         (if_then_else
6458          (match_test "TARGET_POWERPC64")
6459          (const_string "8")
6460          (const_string "16"))))])
6463 ;; Now define ways of moving data around.
6465 ;; Set up a register with a value from the GOT table
6467 (define_expand "movsi_got"
6468   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6469         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6470                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6471   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6472   "
6474   if (GET_CODE (operands[1]) == CONST)
6475     {
6476       rtx offset = const0_rtx;
6477       HOST_WIDE_INT value;
6479       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6480       value = INTVAL (offset);
6481       if (value != 0)
6482         {
6483           rtx tmp = (!can_create_pseudo_p ()
6484                      ? operands[0]
6485                      : gen_reg_rtx (Pmode));
6486           emit_insn (gen_movsi_got (tmp, operands[1]));
6487           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6488           DONE;
6489         }
6490     }
6492   operands[2] = rs6000_got_register (operands[1]);
6495 (define_insn "*movsi_got_internal"
6496   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6497         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6498                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6499                    UNSPEC_MOVSI_GOT))]
6500   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6501   "lwz %0,%a1@got(%2)"
6502   [(set_attr "type" "load")])
6504 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6505 ;; didn't get allocated to a hard register.
6506 (define_split
6507   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6508         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6509                     (match_operand:SI 2 "memory_operand" "")]
6510                    UNSPEC_MOVSI_GOT))]
6511   "DEFAULT_ABI == ABI_V4
6512     && flag_pic == 1
6513     && (reload_in_progress || reload_completed)"
6514   [(set (match_dup 0) (match_dup 2))
6515    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6516                                  UNSPEC_MOVSI_GOT))]
6517   "")
6519 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6520 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6521 ;; and this is even supposed to be faster, but it is simpler not to get
6522 ;; integers in the TOC.
6523 (define_insn "movsi_low"
6524   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6525         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6526                            (match_operand 2 "" ""))))]
6527   "TARGET_MACHO && ! TARGET_64BIT"
6528   "lwz %0,lo16(%2)(%1)"
6529   [(set_attr "type" "load")
6530    (set_attr "length" "4")])
6532 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6533 ;;              STW          STFIWX       STXSIWX      LI           LIS
6534 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6535 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6536 ;;              MF%1         MT%0         MT%0         NOP
6537 (define_insn "*movsi_internal1"
6538   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6539                 "=r,         r,           r,           ?*wI,        ?*wH,
6540                  m,          ?Z,          ?Z,          r,           r,
6541                  r,          ?*wIwH,      ?*wJwK,      ?*wK,        ?*wJwK,
6542                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6543                  r,          *c*l,        *h,          *h")
6545         (match_operand:SI 1 "input_operand"
6546                 "r,          U,           m,           Z,           Z,
6547                  r,          wI,          wH,          I,           L,
6548                  n,          wIwH,        O,           wM,          wB,
6549                  O,          wM,          wS,          r,           wIwH,
6550                  *h,         r,           r,           0"))]
6552   "!TARGET_SINGLE_FPU &&
6553    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6554   "@
6555    mr %0,%1
6556    la %0,%a1
6557    lwz%U1%X1 %0,%1
6558    lfiwzx %0,%y1
6559    lxsiwzx %x0,%y1
6560    stw%U0%X0 %1,%0
6561    stfiwx %1,%y0
6562    stxsiwx %x1,%y0
6563    li %0,%1
6564    lis %0,%v1
6565    #
6566    xxlor %x0,%x1,%x1
6567    xxspltib %x0,0
6568    xxspltib %x0,255
6569    vspltisw %0,%1
6570    xxlxor %x0,%x0,%x0
6571    xxlorc %x0,%x0,%x0
6572    #
6573    mtvsrwz %x0,%1
6574    mfvsrwz %0,%x1
6575    mf%1 %0
6576    mt%0 %1
6577    mt%0 %1
6578    nop"
6579   [(set_attr "type"
6580                 "*,          *,           load,        fpload,      fpload,
6581                  store,      fpstore,     fpstore,     *,           *,
6582                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6583                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6584                  *,           *,           *,           *")
6586    (set_attr "length"
6587                 "4,          4,           4,           4,           4,
6588                  4,          4,           4,           4,           4,
6589                  8,          4,           4,           4,           4,
6590                  4,          4,           8,           4,           4,
6591                  4,          4,           4,           4")])
6593 (define_insn "*movsi_internal1_single"
6594   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6595         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6596   "TARGET_SINGLE_FPU &&
6597    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6598   "@
6599    mr %0,%1
6600    la %0,%a1
6601    lwz%U1%X1 %0,%1
6602    stw%U0%X0 %1,%0
6603    li %0,%1
6604    lis %0,%v1
6605    #
6606    mf%1 %0
6607    mt%0 %1
6608    mt%0 %1
6609    nop
6610    stfs%U0%X0 %1,%0
6611    lfs%U1%X1 %0,%1"
6612   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6613    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6615 ;; Split a load of a large constant into the appropriate two-insn
6616 ;; sequence.
6618 (define_split
6619   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6620         (match_operand:SI 1 "const_int_operand" ""))]
6621   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6622    && (INTVAL (operands[1]) & 0xffff) != 0"
6623   [(set (match_dup 0)
6624         (match_dup 2))
6625    (set (match_dup 0)
6626         (ior:SI (match_dup 0)
6627                 (match_dup 3)))]
6628   "
6630   if (rs6000_emit_set_const (operands[0], operands[1]))
6631     DONE;
6632   else
6633     FAIL;
6636 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6637 (define_split
6638   [(set (match_operand:DI 0 "altivec_register_operand" "")
6639         (match_operand:DI 1 "xxspltib_constant_split" ""))]
6640   "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6641   [(const_int 0)]
6643   rtx op0 = operands[0];
6644   rtx op1 = operands[1];
6645   int r = REGNO (op0);
6646   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6648   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6649   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6650   DONE;
6653 (define_insn "*mov<mode>_internal2"
6654   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6655         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6656                     (const_int 0)))
6657    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6658   ""
6659   "@
6660    cmp<wd>i %2,%0,0
6661    mr. %0,%1
6662    #"
6663   [(set_attr "type" "cmp,logical,cmp")
6664    (set_attr "dot" "yes")
6665    (set_attr "length" "4,4,8")])
6667 (define_split
6668   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6669         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6670                     (const_int 0)))
6671    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6672   "reload_completed"
6673   [(set (match_dup 0) (match_dup 1))
6674    (set (match_dup 2)
6675         (compare:CC (match_dup 0)
6676                     (const_int 0)))]
6677   "")
6679 (define_insn "*movhi_internal"
6680   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6681         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6682   "gpc_reg_operand (operands[0], HImode)
6683    || gpc_reg_operand (operands[1], HImode)"
6684   "@
6685    mr %0,%1
6686    lhz%U1%X1 %0,%1
6687    sth%U0%X0 %1,%0
6688    li %0,%w1
6689    mf%1 %0
6690    mt%0 %1
6691    nop"
6692   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6694 (define_expand "mov<mode>"
6695   [(set (match_operand:INT 0 "general_operand" "")
6696         (match_operand:INT 1 "any_operand" ""))]
6697   ""
6698   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6700 (define_insn "*movqi_internal"
6701   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6702         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6703   "gpc_reg_operand (operands[0], QImode)
6704    || gpc_reg_operand (operands[1], QImode)"
6705   "@
6706    mr %0,%1
6707    lbz%U1%X1 %0,%1
6708    stb%U0%X0 %1,%0
6709    li %0,%1
6710    mf%1 %0
6711    mt%0 %1
6712    nop"
6713   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6715 ;; Here is how to move condition codes around.  When we store CC data in
6716 ;; an integer register or memory, we store just the high-order 4 bits.
6717 ;; This lets us not shift in the most common case of CR0.
6718 (define_expand "movcc"
6719   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6720         (match_operand:CC 1 "nonimmediate_operand" ""))]
6721   ""
6722   "")
6724 (define_insn "*movcc_internal1"
6725   [(set (match_operand:CC 0 "nonimmediate_operand"
6726                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
6727         (match_operand:CC 1 "general_operand"
6728                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
6729   "register_operand (operands[0], CCmode)
6730    || register_operand (operands[1], CCmode)"
6731   "@
6732    mcrf %0,%1
6733    mtcrf 128,%1
6734    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6735    crxor %0,%0,%0
6736    mfcr %0%Q1
6737    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6738    mr %0,%1
6739    li %0,%1
6740    mf%1 %0
6741    mt%0 %1
6742    lwz%U1%X1 %0,%1
6743    stw%U0%X0 %1,%0"
6744   [(set (attr "type")
6745      (cond [(eq_attr "alternative" "0,3")
6746                 (const_string "cr_logical")
6747             (eq_attr "alternative" "1,2")
6748                 (const_string "mtcr")
6749             (eq_attr "alternative" "6,7")
6750                 (const_string "integer")
6751             (eq_attr "alternative" "8")
6752                 (const_string "mfjmpr")
6753             (eq_attr "alternative" "9")
6754                 (const_string "mtjmpr")
6755             (eq_attr "alternative" "10")
6756                 (const_string "load")
6757             (eq_attr "alternative" "11")
6758                 (const_string "store")
6759             (match_test "TARGET_MFCRF")
6760                 (const_string "mfcrf")
6761            ]
6762         (const_string "mfcr")))
6763    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6765 ;; For floating-point, we normally deal with the floating-point registers
6766 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6767 ;; can produce floating-point values in fixed-point registers.  Unless the
6768 ;; value is a simple constant or already in memory, we deal with this by
6769 ;; allocating memory and copying the value explicitly via that memory location.
6771 ;; Move 32-bit binary/decimal floating point
6772 (define_expand "mov<mode>"
6773   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6774         (match_operand:FMOVE32 1 "any_operand" ""))]
6775   "<fmove_ok>"
6776   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6778 (define_split
6779   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6780         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6781   "reload_completed
6782    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6783        || (GET_CODE (operands[0]) == SUBREG
6784            && GET_CODE (SUBREG_REG (operands[0])) == REG
6785            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6786   [(set (match_dup 2) (match_dup 3))]
6787   "
6789   long l;
6791   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6793   if (! TARGET_POWERPC64)
6794     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6795   else
6796     operands[2] = gen_lowpart (SImode, operands[0]);
6798   operands[3] = gen_int_mode (l, SImode);
6801 (define_insn "mov<mode>_hardfloat"
6802   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
6803          "=!r,       <f32_lr>,  <f32_lr2>, <f32_av>,  m,         <f32_sm>,
6804           <f32_sm2>, Z,         <f32_vsx>, !r,        ?<f32_dm>, ?r,
6805           f,         <f32_vsx>, !r,        *c*l,      !r,        *h")
6806         (match_operand:FMOVE32 1 "input_operand"
6807          "m,         <f32_lm>,  <f32_lm2>, Z,         r,         <f32_sr>,
6808           <f32_sr2>, <f32_av>,  <zero_fp>, <zero_fp>, r,         <f32_dm>,
6809           f,         <f32_vsx>, r,         r,         *h,        0"))]
6810   "(gpc_reg_operand (operands[0], <MODE>mode)
6811    || gpc_reg_operand (operands[1], <MODE>mode))
6812    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6813   "@
6814    lwz%U1%X1 %0,%1
6815    <f32_li>
6816    <f32_li2>
6817    <f32_lv>
6818    stw%U0%X0 %1,%0
6819    <f32_si>
6820    <f32_si2>
6821    <f32_sv>
6822    xxlxor %x0,%x0,%x0
6823    li %0,0
6824    mtvsrwz %x0,%1
6825    mfvsrwz %0,%x1
6826    fmr %0,%1
6827    xscpsgndp %x0,%x1,%x1
6828    mr %0,%1
6829    mt%0 %1
6830    mf%1 %0
6831    nop"
6832   [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
6834 (define_insn "*mov<mode>_softfloat"
6835   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6836         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6837   "(gpc_reg_operand (operands[0], <MODE>mode)
6838    || gpc_reg_operand (operands[1], <MODE>mode))
6839    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6840   "@
6841    mr %0,%1
6842    mt%0 %1
6843    mf%1 %0
6844    lwz%U1%X1 %0,%1
6845    stw%U0%X0 %1,%0
6846    li %0,%1
6847    lis %0,%v1
6848    #
6849    #
6850    nop"
6851   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6852    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6855 ;; Move 64-bit binary/decimal floating point
6856 (define_expand "mov<mode>"
6857   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6858         (match_operand:FMOVE64 1 "any_operand" ""))]
6859   ""
6860   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6862 (define_split
6863   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6864         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6865   "! TARGET_POWERPC64 && reload_completed
6866    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6867        || (GET_CODE (operands[0]) == SUBREG
6868            && GET_CODE (SUBREG_REG (operands[0])) == REG
6869            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6870   [(set (match_dup 2) (match_dup 4))
6871    (set (match_dup 3) (match_dup 1))]
6872   "
6874   int endian = (WORDS_BIG_ENDIAN == 0);
6875   HOST_WIDE_INT value = INTVAL (operands[1]);
6877   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6878   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6879   operands[4] = GEN_INT (value >> 32);
6880   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6883 (define_split
6884   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6885         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6886   "! TARGET_POWERPC64 && reload_completed
6887    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6888        || (GET_CODE (operands[0]) == SUBREG
6889            && GET_CODE (SUBREG_REG (operands[0])) == REG
6890            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6891   [(set (match_dup 2) (match_dup 4))
6892    (set (match_dup 3) (match_dup 5))]
6893   "
6895   int endian = (WORDS_BIG_ENDIAN == 0);
6896   long l[2];
6898   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6900   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6901   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6902   operands[4] = gen_int_mode (l[endian], SImode);
6903   operands[5] = gen_int_mode (l[1 - endian], SImode);
6906 (define_split
6907   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6908         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6909   "TARGET_POWERPC64 && reload_completed
6910    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6911        || (GET_CODE (operands[0]) == SUBREG
6912            && GET_CODE (SUBREG_REG (operands[0])) == REG
6913            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6914   [(set (match_dup 2) (match_dup 3))]
6915   "
6917   int endian = (WORDS_BIG_ENDIAN == 0);
6918   long l[2];
6919   HOST_WIDE_INT val;
6921   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6923   operands[2] = gen_lowpart (DImode, operands[0]);
6924   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6925   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6926          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6928   operands[3] = gen_int_mode (val, DImode);
6931 ;; Don't have reload use general registers to load a constant.  It is
6932 ;; less efficient than loading the constant into an FP register, since
6933 ;; it will probably be used there.
6935 ;; The move constraints are ordered to prefer floating point registers before
6936 ;; general purpose registers to avoid doing a store and a load to get the value
6937 ;; into a floating point register when it is needed for a floating point
6938 ;; operation.  Prefer traditional floating point registers over VSX registers,
6939 ;; since the D-form version of the memory instructions does not need a GPR for
6940 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6941 ;; registers.
6943 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6944 ;; except for 0.0 which can be created on VSX with an xor instruction.
6946 (define_insn "*mov<mode>_hardfloat32"
6947   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6948         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6949   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6950    && (gpc_reg_operand (operands[0], <MODE>mode)
6951        || gpc_reg_operand (operands[1], <MODE>mode))"
6952   "@
6953    stfd%U0%X0 %1,%0
6954    lfd%U1%X1 %0,%1
6955    fmr %0,%1
6956    lxsd%U1x %x0,%y1
6957    stxsd%U0x %x1,%y0
6958    lxsd %0,%1
6959    stxsd %1,%0
6960    xxlor %x0,%x1,%x1
6961    xxlxor %x0,%x0,%x0
6962    #
6963    #
6964    #
6965    #"
6966   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6967    (set_attr "size" "64")
6968    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6970 (define_insn "*mov<mode>_softfloat32"
6971   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6972         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6973   "! TARGET_POWERPC64 
6974    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6975        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6976        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6977    && (gpc_reg_operand (operands[0], <MODE>mode)
6978        || gpc_reg_operand (operands[1], <MODE>mode))"
6979   "#"
6980   [(set_attr "type" "store,load,two,*,*,*")
6981    (set_attr "length" "8,8,8,8,12,16")])
6983 ; ld/std require word-aligned displacements -> 'Y' constraint.
6984 ; List Y->r and r->Y before r->r for reload.
6985 (define_insn "*mov<mode>_hardfloat64"
6986   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6987         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6988   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6989    && (gpc_reg_operand (operands[0], <MODE>mode)
6990        || gpc_reg_operand (operands[1], <MODE>mode))"
6991   "@
6992    stfd%U0%X0 %1,%0
6993    lfd%U1%X1 %0,%1
6994    fmr %0,%1
6995    lxsd %0,%1
6996    stxsd %1,%0
6997    lxsd%U1x %x0,%y1
6998    stxsd%U0x %x1,%y0
6999    xxlor %x0,%x1,%x1
7000    xxlxor %x0,%x0,%x0
7001    li %0,0
7002    std%U0%X0 %1,%0
7003    ld%U1%X1 %0,%1
7004    mr %0,%1
7005    mt%0 %1
7006    mf%1 %0
7007    nop
7008    mftgpr %0,%1
7009    mffgpr %0,%1
7010    mfvsrd %0,%x1
7011    mtvsrd %x0,%1"
7012   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7013    (set_attr "size" "64")
7014    (set_attr "length" "4")])
7016 (define_insn "*mov<mode>_softfloat64"
7017   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7018         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7019   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7020    && (gpc_reg_operand (operands[0], <MODE>mode)
7021        || gpc_reg_operand (operands[1], <MODE>mode))"
7022   "@
7023    std%U0%X0 %1,%0
7024    ld%U1%X1 %0,%1
7025    mr %0,%1
7026    mt%0 %1
7027    mf%1 %0
7028    #
7029    #
7030    #
7031    nop"
7032   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7033    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7035 (define_expand "mov<mode>"
7036   [(set (match_operand:FMOVE128 0 "general_operand" "")
7037         (match_operand:FMOVE128 1 "any_operand" ""))]
7038   ""
7039   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7041 ;; It's important to list Y->r and r->Y before r->r because otherwise
7042 ;; reload, given m->r, will try to pick r->r and reload it, which
7043 ;; doesn't make progress.
7045 ;; We can't split little endian direct moves of TDmode, because the words are
7046 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7047 ;; problematical.  Don't allow direct move for this case.
7049 (define_insn_and_split "*mov<mode>_64bit_dm"
7050   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7051         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7052   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7053    && FLOAT128_2REG_P (<MODE>mode)
7054    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7055    && (gpc_reg_operand (operands[0], <MODE>mode)
7056        || gpc_reg_operand (operands[1], <MODE>mode))"
7057   "#"
7058   "&& reload_completed"
7059   [(pc)]
7060 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7061   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7063 (define_insn_and_split "*movtd_64bit_nodm"
7064   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7065         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7066   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7067    && (gpc_reg_operand (operands[0], TDmode)
7068        || gpc_reg_operand (operands[1], TDmode))"
7069   "#"
7070   "&& reload_completed"
7071   [(pc)]
7072 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7073   [(set_attr "length" "8,8,8,12,12,8")])
7075 (define_insn_and_split "*mov<mode>_32bit"
7076   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7077         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7078   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7079    && (FLOAT128_2REG_P (<MODE>mode)
7080        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7081        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7082    && (gpc_reg_operand (operands[0], <MODE>mode)
7083        || gpc_reg_operand (operands[1], <MODE>mode))"
7084   "#"
7085   "&& reload_completed"
7086   [(pc)]
7087 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7088   [(set_attr "length" "8,8,8,8,20,20,16")])
7090 (define_insn_and_split "*mov<mode>_softfloat"
7091   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7092         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7093   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7094    && (gpc_reg_operand (operands[0], <MODE>mode)
7095        || gpc_reg_operand (operands[1], <MODE>mode))"
7096   "#"
7097   "&& reload_completed"
7098   [(pc)]
7099 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7100   [(set_attr "length" "20,20,16")])
7102 (define_expand "extenddf<mode>2"
7103   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7104         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7105   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7106    && TARGET_LONG_DOUBLE_128"
7108   if (FLOAT128_IEEE_P (<MODE>mode))
7109     rs6000_expand_float128_convert (operands[0], operands[1], false);
7110   else if (TARGET_E500_DOUBLE)
7111     {
7112       gcc_assert (<MODE>mode == TFmode);
7113       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7114     }
7115   else if (TARGET_VSX)
7116     {
7117       if (<MODE>mode == TFmode)
7118         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7119       else if (<MODE>mode == IFmode)
7120         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7121       else
7122         gcc_unreachable ();
7123     }
7124    else
7125     {
7126       rtx zero = gen_reg_rtx (DFmode);
7127       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7129       if (<MODE>mode == TFmode)
7130         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7131       else if (<MODE>mode == IFmode)
7132         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7133       else
7134         gcc_unreachable ();
7135     }
7136   DONE;
7139 ;; Allow memory operands for the source to be created by the combiner.
7140 (define_insn_and_split "extenddf<mode>2_fprs"
7141   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7142         (float_extend:IBM128
7143          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7144    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7145   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7146    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7147   "#"
7148   "&& reload_completed"
7149   [(set (match_dup 3) (match_dup 1))
7150    (set (match_dup 4) (match_dup 2))]
7152   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7153   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7155   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7156   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7159 (define_insn_and_split "extenddf<mode>2_vsx"
7160   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7161         (float_extend:IBM128
7162          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7163   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7164   "#"
7165   "&& reload_completed"
7166   [(set (match_dup 2) (match_dup 1))
7167    (set (match_dup 3) (match_dup 4))]
7169   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7170   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7172   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7173   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7174   operands[4] = CONST0_RTX (DFmode);
7177 (define_expand "extendsf<mode>2"
7178   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7179         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7180   "TARGET_HARD_FLOAT
7181    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7182    && TARGET_LONG_DOUBLE_128"
7184   if (FLOAT128_IEEE_P (<MODE>mode))
7185     rs6000_expand_float128_convert (operands[0], operands[1], false);
7186   else
7187     {
7188       rtx tmp = gen_reg_rtx (DFmode);
7189       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7190       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7191     }
7192   DONE;
7195 (define_expand "trunc<mode>df2"
7196   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7197         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7198   "TARGET_HARD_FLOAT
7199    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7200    && TARGET_LONG_DOUBLE_128"
7202   if (FLOAT128_IEEE_P (<MODE>mode))
7203     {
7204       rs6000_expand_float128_convert (operands[0], operands[1], false);
7205       DONE;
7206     }
7209 (define_insn_and_split "trunc<mode>df2_internal1"
7210   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7211         (float_truncate:DF
7212          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7213   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7214    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7215   "@
7216    #
7217    fmr %0,%1"
7218   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7219   [(const_int 0)]
7221   emit_note (NOTE_INSN_DELETED);
7222   DONE;
7224   [(set_attr "type" "fpsimple")])
7226 (define_insn "trunc<mode>df2_internal2"
7227   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7228         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7229   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7230    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7231   "fadd %0,%1,%L1"
7232   [(set_attr "type" "fp")
7233    (set_attr "fp_type" "fp_addsub_d")])
7235 (define_expand "trunc<mode>sf2"
7236   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7237         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7238   "TARGET_HARD_FLOAT
7239    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7240    && TARGET_LONG_DOUBLE_128"
7242   if (FLOAT128_IEEE_P (<MODE>mode))
7243     rs6000_expand_float128_convert (operands[0], operands[1], false);
7244   else if (TARGET_E500_DOUBLE)
7245     {
7246       gcc_assert (<MODE>mode == TFmode);
7247       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7248     }
7249   else if (<MODE>mode == TFmode)
7250     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7251   else if (<MODE>mode == IFmode)
7252     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7253   else
7254     gcc_unreachable ();
7255   DONE;
7258 (define_insn_and_split "trunc<mode>sf2_fprs"
7259   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7260         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7261    (clobber (match_scratch:DF 2 "=d"))]
7262   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7263    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7264   "#"
7265   "&& reload_completed"
7266   [(set (match_dup 2)
7267         (float_truncate:DF (match_dup 1)))
7268    (set (match_dup 0)
7269         (float_truncate:SF (match_dup 2)))]
7270   "")
7272 (define_expand "floatsi<mode>2"
7273   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7274         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7275   "TARGET_HARD_FLOAT
7276    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7277    && TARGET_LONG_DOUBLE_128"
7279   if (FLOAT128_IEEE_P (<MODE>mode))
7280     rs6000_expand_float128_convert (operands[0], operands[1], false);
7281   else
7282     {
7283       rtx tmp = gen_reg_rtx (DFmode);
7284       expand_float (tmp, operands[1], false);
7285       if (<MODE>mode == TFmode)
7286         emit_insn (gen_extenddftf2 (operands[0], tmp));
7287       else if (<MODE>mode == IFmode)
7288         emit_insn (gen_extenddfif2 (operands[0], tmp));
7289       else
7290         gcc_unreachable ();
7291     }
7292   DONE;
7295 ; fadd, but rounding towards zero.
7296 ; This is probably not the optimal code sequence.
7297 (define_insn "fix_trunc_helper<mode>"
7298   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7299         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7300                    UNSPEC_FIX_TRUNC_TF))
7301    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7302   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7303    && FLOAT128_IBM_P (<MODE>mode)"
7304   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7305   [(set_attr "type" "fp")
7306    (set_attr "length" "20")])
7308 (define_expand "fix_trunc<mode>si2"
7309   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7310         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7311   "TARGET_HARD_FLOAT
7312    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7314   if (FLOAT128_IEEE_P (<MODE>mode))
7315     rs6000_expand_float128_convert (operands[0], operands[1], false);
7316   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7317     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7318   else if (<MODE>mode == TFmode)
7319     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7320   else if (<MODE>mode == IFmode)
7321     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7322   else
7323     gcc_unreachable ();
7324   DONE;
7327 (define_expand "fix_trunc<mode>si2_fprs"
7328   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7329                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7330               (clobber (match_dup 2))
7331               (clobber (match_dup 3))
7332               (clobber (match_dup 4))
7333               (clobber (match_dup 5))])]
7334   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7336   operands[2] = gen_reg_rtx (DFmode);
7337   operands[3] = gen_reg_rtx (DFmode);
7338   operands[4] = gen_reg_rtx (DImode);
7339   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7342 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7343   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7344         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7345    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7346    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7347    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7348    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7349   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7350   "#"
7351   ""
7352   [(pc)]
7354   rtx lowword;
7355   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7356                                          operands[3]));
7358   gcc_assert (MEM_P (operands[5]));
7359   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7361   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7362   emit_move_insn (operands[5], operands[4]);
7363   emit_move_insn (operands[0], lowword);
7364   DONE;
7367 (define_expand "fix_trunc<mode>di2"
7368   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7369         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7370   "TARGET_FLOAT128_TYPE"
7372   rs6000_expand_float128_convert (operands[0], operands[1], false);
7373   DONE;
7376 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7377   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7378         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7379   "TARGET_FLOAT128_TYPE"
7381   rs6000_expand_float128_convert (operands[0], operands[1], true);
7382   DONE;
7385 (define_expand "floatdi<mode>2"
7386   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7387         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7388   "TARGET_FLOAT128_TYPE"
7390   rs6000_expand_float128_convert (operands[0], operands[1], false);
7391   DONE;
7394 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7395   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7396         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7397   "TARGET_FLOAT128_TYPE"
7399   rs6000_expand_float128_convert (operands[0], operands[1], true);
7400   DONE;
7403 (define_expand "neg<mode>2"
7404   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7405         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7406   "FLOAT128_IEEE_P (<MODE>mode)
7407    || (FLOAT128_IBM_P (<MODE>mode)
7408        && TARGET_HARD_FLOAT
7409        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7410   "
7412   if (FLOAT128_IEEE_P (<MODE>mode))
7413     {
7414       if (TARGET_FLOAT128_HW)
7415         {
7416           if (<MODE>mode == TFmode)
7417             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7418           else if (<MODE>mode == KFmode)
7419             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7420           else
7421             gcc_unreachable ();
7422         }
7423       else if (TARGET_FLOAT128_TYPE)
7424         {
7425           if (<MODE>mode == TFmode)
7426             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7427           else if (<MODE>mode == KFmode)
7428             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7429           else
7430             gcc_unreachable ();
7431         }
7432       else
7433         {
7434           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7435           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7436                                                 <MODE>mode, 1,
7437                                                 operands[1], <MODE>mode);
7439           if (target && !rtx_equal_p (target, operands[0]))
7440             emit_move_insn (operands[0], target);
7441         }
7442       DONE;
7443     }
7446 (define_insn "neg<mode>2_internal"
7447   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7448         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7449   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7450   "*
7452   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7453     return \"fneg %L0,%L1\;fneg %0,%1\";
7454   else
7455     return \"fneg %0,%1\;fneg %L0,%L1\";
7457   [(set_attr "type" "fpsimple")
7458    (set_attr "length" "8")])
7460 (define_expand "abs<mode>2"
7461   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7462         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7463   "FLOAT128_IEEE_P (<MODE>mode)
7464    || (FLOAT128_IBM_P (<MODE>mode)
7465        && TARGET_HARD_FLOAT
7466        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7467   "
7469   rtx label;
7471   if (FLOAT128_IEEE_P (<MODE>mode))
7472     {
7473       if (TARGET_FLOAT128_HW)
7474         {
7475           if (<MODE>mode == TFmode)
7476             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7477           else if (<MODE>mode == KFmode)
7478             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7479           else
7480             FAIL;
7481           DONE;
7482         }
7483       else if (TARGET_FLOAT128_TYPE)
7484         {
7485           if (<MODE>mode == TFmode)
7486             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7487           else if (<MODE>mode == KFmode)
7488             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7489           else
7490             FAIL;
7491           DONE;
7492         }
7493       else
7494         FAIL;
7495     }
7497   label = gen_label_rtx ();
7498   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7499     {
7500       if (flag_finite_math_only && !flag_trapping_math)
7501         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7502       else
7503         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7504     }
7505   else if (<MODE>mode == TFmode)
7506     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7507   else if (<MODE>mode == TFmode)
7508     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7509   else
7510     FAIL;
7511   emit_label (label);
7512   DONE;
7515 (define_expand "abs<mode>2_internal"
7516   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7517         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7518    (set (match_dup 3) (match_dup 5))
7519    (set (match_dup 5) (abs:DF (match_dup 5)))
7520    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7521    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7522                            (label_ref (match_operand 2 "" ""))
7523                            (pc)))
7524    (set (match_dup 6) (neg:DF (match_dup 6)))]
7525   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7526    && TARGET_LONG_DOUBLE_128"
7527   "
7529   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7530   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7531   operands[3] = gen_reg_rtx (DFmode);
7532   operands[4] = gen_reg_rtx (CCFPmode);
7533   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7534   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7538 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7539 ;; register
7541 (define_expand "ieee_128bit_negative_zero"
7542   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7543   "TARGET_FLOAT128_TYPE"
7545   rtvec v = rtvec_alloc (16);
7546   int i, high;
7548   for (i = 0; i < 16; i++)
7549     RTVEC_ELT (v, i) = const0_rtx;
7551   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7552   RTVEC_ELT (v, high) = GEN_INT (0x80);
7554   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7555   DONE;
7558 ;; IEEE 128-bit negate
7560 ;; We have 2 insns here for negate and absolute value.  The first uses
7561 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7562 ;; insns, and second insn after the first split pass loads up the bit to
7563 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7564 ;; neg/abs to create the constant just once.
7566 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7567   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7568         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7569    (clobber (match_scratch:V16QI 2 "=v"))]
7570   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7571   "#"
7572   "&& 1"
7573   [(parallel [(set (match_dup 0)
7574                    (neg:IEEE128 (match_dup 1)))
7575               (use (match_dup 2))])]
7577   if (GET_CODE (operands[2]) == SCRATCH)
7578     operands[2] = gen_reg_rtx (V16QImode);
7580   operands[3] = gen_reg_rtx (V16QImode);
7581   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7583   [(set_attr "length" "8")
7584    (set_attr "type" "vecsimple")])
7586 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7587   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7588         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7589    (use (match_operand:V16QI 2 "register_operand" "v"))]
7590   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7591   "xxlxor %x0,%x1,%x2"
7592   [(set_attr "type" "veclogical")])
7594 ;; IEEE 128-bit absolute value
7595 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7596   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7597         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7598    (clobber (match_scratch:V16QI 2 "=v"))]
7599   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7600   "#"
7601   "&& 1"
7602   [(parallel [(set (match_dup 0)
7603                    (abs:IEEE128 (match_dup 1)))
7604               (use (match_dup 2))])]
7606   if (GET_CODE (operands[2]) == SCRATCH)
7607     operands[2] = gen_reg_rtx (V16QImode);
7609   operands[3] = gen_reg_rtx (V16QImode);
7610   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7612   [(set_attr "length" "8")
7613    (set_attr "type" "vecsimple")])
7615 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7616   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7617         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7618    (use (match_operand:V16QI 2 "register_operand" "v"))]
7619   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7620   "xxlandc %x0,%x1,%x2"
7621   [(set_attr "type" "veclogical")])
7623 ;; IEEE 128-bit negative absolute value
7624 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7625   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7626         (neg:IEEE128
7627          (abs:IEEE128
7628           (match_operand:IEEE128 1 "register_operand" "wa"))))
7629    (clobber (match_scratch:V16QI 2 "=v"))]
7630   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
7631    && FLOAT128_IEEE_P (<MODE>mode)"
7632   "#"
7633   "&& 1"
7634   [(parallel [(set (match_dup 0)
7635                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7636               (use (match_dup 2))])]
7638   if (GET_CODE (operands[2]) == SCRATCH)
7639     operands[2] = gen_reg_rtx (V16QImode);
7641   operands[3] = gen_reg_rtx (V16QImode);
7642   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7644   [(set_attr "length" "8")
7645    (set_attr "type" "vecsimple")])
7647 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7648   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7649         (neg:IEEE128
7650          (abs:IEEE128
7651           (match_operand:IEEE128 1 "register_operand" "wa"))))
7652    (use (match_operand:V16QI 2 "register_operand" "v"))]
7653   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7654   "xxlor %x0,%x1,%x2"
7655   [(set_attr "type" "veclogical")])
7657 ;; Float128 conversion functions.  These expand to library function calls.
7658 ;; We use expand to convert from IBM double double to IEEE 128-bit
7659 ;; and trunc for the opposite.
7660 (define_expand "extendiftf2"
7661   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7662         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7663   "TARGET_FLOAT128_TYPE"
7665   rs6000_expand_float128_convert (operands[0], operands[1], false);
7666   DONE;
7669 (define_expand "extendifkf2"
7670   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7671         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7672   "TARGET_FLOAT128_TYPE"
7674   rs6000_expand_float128_convert (operands[0], operands[1], false);
7675   DONE;
7678 (define_expand "extendtfkf2"
7679   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7680         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7681   "TARGET_FLOAT128_TYPE"
7683   rs6000_expand_float128_convert (operands[0], operands[1], false);
7684   DONE;
7687 (define_expand "trunciftf2"
7688   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7689         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7690   "TARGET_FLOAT128_TYPE"
7692   rs6000_expand_float128_convert (operands[0], operands[1], false);
7693   DONE;
7696 (define_expand "truncifkf2"
7697   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7698         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7699   "TARGET_FLOAT128_TYPE"
7701   rs6000_expand_float128_convert (operands[0], operands[1], false);
7702   DONE;
7705 (define_expand "trunckftf2"
7706   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7707         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7708   "TARGET_FLOAT128_TYPE"
7710   rs6000_expand_float128_convert (operands[0], operands[1], false);
7711   DONE;
7714 (define_expand "trunctfif2"
7715   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7716         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7717   "TARGET_FLOAT128_TYPE"
7719   rs6000_expand_float128_convert (operands[0], operands[1], false);
7720   DONE;
7724 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7725 ;; must have 3 arguments, and scratch register constraint must be a single
7726 ;; constraint.
7728 ;; Reload patterns to support gpr load/store with misaligned mem.
7729 ;; and multiple gpr load/store at offset >= 0xfffc
7730 (define_expand "reload_<mode>_store"
7731   [(parallel [(match_operand 0 "memory_operand" "=m")
7732               (match_operand 1 "gpc_reg_operand" "r")
7733               (match_operand:GPR 2 "register_operand" "=&b")])]
7734   ""
7736   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7737   DONE;
7740 (define_expand "reload_<mode>_load"
7741   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7742               (match_operand 1 "memory_operand" "m")
7743               (match_operand:GPR 2 "register_operand" "=b")])]
7744   ""
7746   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7747   DONE;
7751 ;; Reload patterns for various types using the vector registers.  We may need
7752 ;; an additional base register to convert the reg+offset addressing to reg+reg
7753 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7754 ;; index register for gpr registers.
7755 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7756   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7757               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7758               (match_operand:P 2 "register_operand" "=b")])]
7759   "<P:tptrsize>"
7761   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7762   DONE;
7765 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7766   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7767               (match_operand:RELOAD 1 "memory_operand" "m")
7768               (match_operand:P 2 "register_operand" "=b")])]
7769   "<P:tptrsize>"
7771   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7772   DONE;
7776 ;; Reload sometimes tries to move the address to a GPR, and can generate
7777 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7778 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7780 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7781   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7782         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7783                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7784                (const_int -16)))]
7785   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7786   "#"
7787   "&& reload_completed"
7788   [(set (match_dup 0)
7789         (plus:P (match_dup 1)
7790                 (match_dup 2)))
7791    (set (match_dup 0)
7792         (and:P (match_dup 0)
7793                (const_int -16)))])
7795 ;; Power8 merge instructions to allow direct move to/from floating point
7796 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7797 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7798 ;; value, since it is allocated in reload and not all of the flow information
7799 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7800 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7801 ;; schedule other instructions between the two instructions.
7803 (define_insn "p8_fmrgow_<mode>"
7804   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7805         (unspec:FMOVE64X [
7806                 (match_operand:DF 1 "register_operand" "d")
7807                 (match_operand:DF 2 "register_operand" "d")]
7808                          UNSPEC_P8V_FMRGOW))]
7809   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7810   "fmrgow %0,%1,%2"
7811   [(set_attr "type" "fpsimple")])
7813 (define_insn "p8_mtvsrwz"
7814   [(set (match_operand:DF 0 "register_operand" "=d")
7815         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7816                    UNSPEC_P8V_MTVSRWZ))]
7817   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7818   "mtvsrwz %x0,%1"
7819   [(set_attr "type" "mftgpr")])
7821 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7822   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7823         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7824                          UNSPEC_P8V_RELOAD_FROM_GPR))
7825    (clobber (match_operand:IF 2 "register_operand" "=d"))]
7826   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7827   "#"
7828   "&& reload_completed"
7829   [(const_int 0)]
7831   rtx dest = operands[0];
7832   rtx src = operands[1];
7833   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7834   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7835   rtx gpr_hi_reg = gen_highpart (SImode, src);
7836   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7838   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7839   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7840   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7841   DONE;
7843   [(set_attr "length" "12")
7844    (set_attr "type" "three")])
7846 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7847 (define_insn "p8_mtvsrd_df"
7848   [(set (match_operand:DF 0 "register_operand" "=wa")
7849         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7850                    UNSPEC_P8V_MTVSRD))]
7851   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7852   "mtvsrd %x0,%1"
7853   [(set_attr "type" "mftgpr")])
7855 (define_insn "p8_xxpermdi_<mode>"
7856   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7857         (unspec:FMOVE128_GPR [
7858                 (match_operand:DF 1 "register_operand" "wa")
7859                 (match_operand:DF 2 "register_operand" "wa")]
7860                 UNSPEC_P8V_XXPERMDI))]
7861   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7862   "xxpermdi %x0,%x1,%x2,0"
7863   [(set_attr "type" "vecperm")])
7865 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7866   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7867         (unspec:FMOVE128_GPR
7868          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7869          UNSPEC_P8V_RELOAD_FROM_GPR))
7870    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7871   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7872   "#"
7873   "&& reload_completed"
7874   [(const_int 0)]
7876   rtx dest = operands[0];
7877   rtx src = operands[1];
7878   /* You might think that we could use op0 as one temp and a DF clobber
7879      as op2, but you'd be wrong.  Secondary reload move patterns don't
7880      check for overlap of the clobber and the destination.  */
7881   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7882   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7883   rtx gpr_hi_reg = gen_highpart (DImode, src);
7884   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7886   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7887   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7888   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7889   DONE;
7891   [(set_attr "length" "12")
7892    (set_attr "type" "three")])
7894 (define_split
7895   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7896         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7897   "reload_completed
7898    && (int_reg_operand (operands[0], <MODE>mode)
7899        || int_reg_operand (operands[1], <MODE>mode))
7900    && (!TARGET_DIRECT_MOVE_128
7901        || (!vsx_register_operand (operands[0], <MODE>mode)
7902            && !vsx_register_operand (operands[1], <MODE>mode)))"
7903   [(pc)]
7904 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7906 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7907 ;; type is stored internally as double precision in the VSX registers, we have
7908 ;; to convert it from the vector format.
7909 (define_insn "p8_mtvsrd_sf"
7910   [(set (match_operand:SF 0 "register_operand" "=wa")
7911         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7912                    UNSPEC_P8V_MTVSRD))]
7913   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7914   "mtvsrd %x0,%1"
7915   [(set_attr "type" "mftgpr")])
7917 (define_insn_and_split "reload_vsx_from_gprsf"
7918   [(set (match_operand:SF 0 "register_operand" "=wa")
7919         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7920                    UNSPEC_P8V_RELOAD_FROM_GPR))
7921    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7922   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7923   "#"
7924   "&& reload_completed"
7925   [(const_int 0)]
7927   rtx op0 = operands[0];
7928   rtx op1 = operands[1];
7929   rtx op2 = operands[2];
7930   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7932   /* Move SF value to upper 32-bits for xscvspdpn.  */
7933   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7934   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7935   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7936   DONE;
7938   [(set_attr "length" "8")
7939    (set_attr "type" "two")])
7941 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7942 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7943 ;; and then doing a move of that.
7944 (define_insn "p8_mfvsrd_3_<mode>"
7945   [(set (match_operand:DF 0 "register_operand" "=r")
7946         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7947                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7948   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7949   "mfvsrd %0,%x1"
7950   [(set_attr "type" "mftgpr")])
7952 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7953   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7954         (unspec:FMOVE128_GPR
7955          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7956          UNSPEC_P8V_RELOAD_FROM_VSX))
7957    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7958   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7959   "#"
7960   "&& reload_completed"
7961   [(const_int 0)]
7963   rtx dest = operands[0];
7964   rtx src = operands[1];
7965   rtx tmp = operands[2];
7966   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7967   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7969   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7970   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7971   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7972   DONE;
7974   [(set_attr "length" "12")
7975    (set_attr "type" "three")])
7977 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7978 ;; type is stored internally as double precision, we have to convert it to the
7979 ;; vector format.
7981 (define_insn_and_split "reload_gpr_from_vsxsf"
7982   [(set (match_operand:SF 0 "register_operand" "=r")
7983         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7984                    UNSPEC_P8V_RELOAD_FROM_VSX))
7985    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7986   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7987   "#"
7988   "&& reload_completed"
7989   [(const_int 0)]
7991   rtx op0 = operands[0];
7992   rtx op1 = operands[1];
7993   rtx op2 = operands[2];
7994   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7996   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7997   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7998   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7999   DONE;
8001   [(set_attr "length" "12")
8002    (set_attr "type" "three")])
8004 (define_insn "p8_mfvsrd_4_disf"
8005   [(set (match_operand:DI 0 "register_operand" "=r")
8006         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8007                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8008   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8009   "mfvsrd %0,%x1"
8010   [(set_attr "type" "mftgpr")])
8013 ;; Next come the multi-word integer load and store and the load and store
8014 ;; multiple insns.
8016 ;; List r->r after r->Y, otherwise reload will try to reload a
8017 ;; non-offsettable address by using r->r which won't make progress.
8018 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8019 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8021 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8022 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8023 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8024 ;;        AVX const  
8026 (define_insn "*movdi_internal32"
8027   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8028          "=Y,        r,         r,         ?m,        ?*d,        ?*d,
8029           r,         ?wY,       ?Z,        ?*wb,      ?*wv,       ?wi,
8030           ?wo,       ?wo,       ?wv,       ?wi,       ?wi,        ?wv,
8031           ?wv")
8033         (match_operand:DI 1 "input_operand"
8034           "r,        Y,         r,         d,         m,          d,
8035            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8036            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8037            wB"))]
8039   "! TARGET_POWERPC64
8040    && (gpc_reg_operand (operands[0], DImode)
8041        || gpc_reg_operand (operands[1], DImode))"
8042   "@
8043    #
8044    #
8045    #
8046    stfd%U0%X0 %1,%0
8047    lfd%U1%X1 %0,%1
8048    fmr %0,%1
8049    #
8050    stxsd %1,%0
8051    stxsdx %x1,%y0
8052    lxsd %0,%1
8053    lxsdx %x0,%y1
8054    xxlor %x0,%x1,%x1
8055    xxspltib %x0,0
8056    xxspltib %x0,255
8057    vspltisw %0,%1
8058    xxlxor %x0,%x0,%x0
8059    xxlorc %x0,%x0,%x0
8060    #
8061    #"
8062   [(set_attr "type"
8063                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8064                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8065                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8066                 vecsimple")
8067    (set_attr "size" "64")])
8069 (define_split
8070   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8071         (match_operand:DI 1 "const_int_operand" ""))]
8072   "! TARGET_POWERPC64 && reload_completed
8073    && gpr_or_gpr_p (operands[0], operands[1])
8074    && !direct_move_p (operands[0], operands[1])"
8075   [(set (match_dup 2) (match_dup 4))
8076    (set (match_dup 3) (match_dup 1))]
8077   "
8079   HOST_WIDE_INT value = INTVAL (operands[1]);
8080   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8081                                        DImode);
8082   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8083                                        DImode);
8084   operands[4] = GEN_INT (value >> 32);
8085   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8088 (define_split
8089   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8090         (match_operand:DIFD 1 "input_operand" ""))]
8091   "reload_completed && !TARGET_POWERPC64
8092    && gpr_or_gpr_p (operands[0], operands[1])
8093    && !direct_move_p (operands[0], operands[1])"
8094   [(pc)]
8095 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8097 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8098 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8099 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8100 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8101 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8102 (define_insn "*movdi_internal64"
8103   [(set (match_operand:DI 0 "nonimmediate_operand"
8104                "=Y,        r,         r,         r,         r,          r,
8105                 ?m,        ?*d,       ?*d,       ?wY,       ?Z,         ?*wb,
8106                 ?*wv,      ?wi,       ?wo,       ?wo,       ?wv,        ?wi,
8107                 ?wi,       ?wv,       ?wv,       r,         *h,         *h,
8108                 ?*r,       ?*wg,      ?*r,       ?*wj")
8110         (match_operand:DI 1 "input_operand"
8111                 "r,        Y,         r,         I,         L,          nF,
8112                  d,        m,         d,         wb,        wv,         wY,
8113                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8114                  wM,       wS,        wB,        *h,        r,          0,
8115                  wg,       r,         wj,        r"))]
8117   "TARGET_POWERPC64
8118    && (gpc_reg_operand (operands[0], DImode)
8119        || gpc_reg_operand (operands[1], DImode))"
8120   "@
8121    std%U0%X0 %1,%0
8122    ld%U1%X1 %0,%1
8123    mr %0,%1
8124    li %0,%1
8125    lis %0,%v1
8126    #
8127    stfd%U0%X0 %1,%0
8128    lfd%U1%X1 %0,%1
8129    fmr %0,%1
8130    stxsd %1,%0
8131    stxsdx %x1,%y0
8132    lxsd %0,%1
8133    lxsdx %x0,%y1
8134    xxlor %x0,%x1,%x1
8135    xxspltib %x0,0
8136    xxspltib %x0,255
8137    vspltisw %0,%1
8138    xxlxor %x0,%x0,%x0
8139    xxlorc %x0,%x0,%x0
8140    #
8141    #
8142    mf%1 %0
8143    mt%0 %1
8144    nop
8145    mftgpr %0,%1
8146    mffgpr %0,%1
8147    mfvsrd %0,%x1
8148    mtvsrd %x0,%1"
8149   [(set_attr "type"
8150                "store,      load,       *,         *,         *,         *,
8151                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8152                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8153                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8154                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8156    (set_attr "size" "64")
8157    (set_attr "length"
8158                "4,         4,         4,         4,         4,          20,
8159                 4,         4,         4,         4,         4,          4,
8160                 4,         4,         4,         4,         4,          8,
8161                 8,         4,         4,         4,         4,          4,
8162                 4,         4,         4,         4")])
8164 ; Some DImode loads are best done as a load of -1 followed by a mask
8165 ; instruction.
8166 (define_split
8167   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8168         (match_operand:DI 1 "const_int_operand"))]
8169   "TARGET_POWERPC64
8170    && num_insns_constant (operands[1], DImode) > 1
8171    && rs6000_is_valid_and_mask (operands[1], DImode)"
8172   [(set (match_dup 0)
8173         (const_int -1))
8174    (set (match_dup 0)
8175         (and:DI (match_dup 0)
8176                 (match_dup 1)))]
8177   "")
8179 ;; Split a load of a large constant into the appropriate five-instruction
8180 ;; sequence.  Handle anything in a constant number of insns.
8181 ;; When non-easy constants can go in the TOC, this should use
8182 ;; easy_fp_constant predicate.
8183 (define_split
8184   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8185         (match_operand:DI 1 "const_int_operand" ""))]
8186   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8187   [(set (match_dup 0) (match_dup 2))
8188    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8189   "
8191   if (rs6000_emit_set_const (operands[0], operands[1]))
8192     DONE;
8193   else
8194     FAIL;
8197 (define_split
8198   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8199         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8200   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8201   [(set (match_dup 0) (match_dup 2))
8202    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8203   "
8205   if (rs6000_emit_set_const (operands[0], operands[1]))
8206     DONE;
8207   else
8208     FAIL;
8211 (define_split
8212   [(set (match_operand:DI 0 "altivec_register_operand" "")
8213         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8214   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8215   [(const_int 0)]
8217   rtx op0 = operands[0];
8218   rtx op1 = operands[1];
8219   int r = REGNO (op0);
8220   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8222   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8223   if (op1 != const0_rtx && op1 != constm1_rtx)
8224     {
8225       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8226       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8227     }
8228   DONE;
8231 (define_split
8232   [(set (match_operand:DI 0 "altivec_register_operand" "")
8233         (match_operand:DI 1 "xxspltib_constant_split" ""))]
8234   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8235   [(const_int 0)]
8237   rtx op0 = operands[0];
8238   rtx op1 = operands[1];
8239   int r = REGNO (op0);
8240   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8242   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8243   emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8244   DONE;
8248 ;; TImode/PTImode is similar, except that we usually want to compute the
8249 ;; address into a register and use lsi/stsi (the exception is during reload).
8251 (define_insn "*mov<mode>_string"
8252   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8253         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8254   "! TARGET_POWERPC64
8255    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8256    && (gpc_reg_operand (operands[0], <MODE>mode)
8257        || gpc_reg_operand (operands[1], <MODE>mode))"
8258   "*
8260   switch (which_alternative)
8261     {
8262     default:
8263       gcc_unreachable ();
8264     case 0:
8265       if (TARGET_STRING)
8266         return \"stswi %1,%P0,16\";
8267       /* FALLTHRU */
8268     case 1:
8269       return \"#\";
8270     case 2:
8271       /* If the address is not used in the output, we can use lsi.  Otherwise,
8272          fall through to generating four loads.  */
8273       if (TARGET_STRING
8274           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8275         return \"lswi %0,%P1,16\";
8276       /* fall through */
8277     case 3:
8278     case 4:
8279     case 5:
8280       return \"#\";
8281     }
8283   [(set_attr "type" "store,store,load,load,*,*")
8284    (set_attr "update" "yes")
8285    (set_attr "indexed" "yes")
8286    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8287                                           (const_string "always")
8288                                           (const_string "conditional")))])
8290 (define_insn "*mov<mode>_ppc64"
8291   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8292         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8293   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8294    && (gpc_reg_operand (operands[0], <MODE>mode)
8295        || gpc_reg_operand (operands[1], <MODE>mode)))"
8297   return rs6000_output_move_128bit (operands);
8299   [(set_attr "type" "store,store,load,load,*,*")
8300    (set_attr "length" "8")])
8302 (define_split
8303   [(set (match_operand:TI2 0 "int_reg_operand" "")
8304         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8305   "TARGET_POWERPC64
8306    && (VECTOR_MEM_NONE_P (<MODE>mode)
8307        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8308   [(set (match_dup 2) (match_dup 4))
8309    (set (match_dup 3) (match_dup 5))]
8310   "
8312   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8313                                        <MODE>mode);
8314   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8315                                        <MODE>mode);
8316   if (CONST_WIDE_INT_P (operands[1]))
8317     {
8318       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8319       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8320     }
8321   else if (CONST_INT_P (operands[1]))
8322     {
8323       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8324       operands[5] = operands[1];
8325     }
8326   else
8327     FAIL;
8330 (define_split
8331   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8332         (match_operand:TI2 1 "input_operand" ""))]
8333   "reload_completed
8334    && gpr_or_gpr_p (operands[0], operands[1])
8335    && !direct_move_p (operands[0], operands[1])
8336    && !quad_load_store_p (operands[0], operands[1])"
8337   [(pc)]
8338 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8340 (define_expand "load_multiple"
8341   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8342                           (match_operand:SI 1 "" ""))
8343                      (use (match_operand:SI 2 "" ""))])]
8344   "TARGET_STRING && !TARGET_POWERPC64"
8345   "
8347   int regno;
8348   int count;
8349   rtx op1;
8350   int i;
8352   /* Support only loading a constant number of fixed-point registers from
8353      memory and only bother with this if more than two; the machine
8354      doesn't support more than eight.  */
8355   if (GET_CODE (operands[2]) != CONST_INT
8356       || INTVAL (operands[2]) <= 2
8357       || INTVAL (operands[2]) > 8
8358       || GET_CODE (operands[1]) != MEM
8359       || GET_CODE (operands[0]) != REG
8360       || REGNO (operands[0]) >= 32)
8361     FAIL;
8363   count = INTVAL (operands[2]);
8364   regno = REGNO (operands[0]);
8366   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8367   op1 = replace_equiv_address (operands[1],
8368                                force_reg (SImode, XEXP (operands[1], 0)));
8370   for (i = 0; i < count; i++)
8371     XVECEXP (operands[3], 0, i)
8372       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8373                      adjust_address_nv (op1, SImode, i * 4));
8376 (define_insn "*ldmsi8"
8377   [(match_parallel 0 "load_multiple_operation"
8378     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8379           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8380      (set (match_operand:SI 3 "gpc_reg_operand" "")
8381           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8382      (set (match_operand:SI 4 "gpc_reg_operand" "")
8383           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8384      (set (match_operand:SI 5 "gpc_reg_operand" "")
8385           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8386      (set (match_operand:SI 6 "gpc_reg_operand" "")
8387           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8388      (set (match_operand:SI 7 "gpc_reg_operand" "")
8389           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8390      (set (match_operand:SI 8 "gpc_reg_operand" "")
8391           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8392      (set (match_operand:SI 9 "gpc_reg_operand" "")
8393           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8394   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8395   "*
8396 { return rs6000_output_load_multiple (operands); }"
8397   [(set_attr "type" "load")
8398    (set_attr "update" "yes")
8399    (set_attr "indexed" "yes")
8400    (set_attr "length" "32")])
8402 (define_insn "*ldmsi7"
8403   [(match_parallel 0 "load_multiple_operation"
8404     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8405           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8406      (set (match_operand:SI 3 "gpc_reg_operand" "")
8407           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8408      (set (match_operand:SI 4 "gpc_reg_operand" "")
8409           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8410      (set (match_operand:SI 5 "gpc_reg_operand" "")
8411           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8412      (set (match_operand:SI 6 "gpc_reg_operand" "")
8413           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8414      (set (match_operand:SI 7 "gpc_reg_operand" "")
8415           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8416      (set (match_operand:SI 8 "gpc_reg_operand" "")
8417           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8418   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8419   "*
8420 { return rs6000_output_load_multiple (operands); }"
8421   [(set_attr "type" "load")
8422    (set_attr "update" "yes")
8423    (set_attr "indexed" "yes")
8424    (set_attr "length" "32")])
8426 (define_insn "*ldmsi6"
8427   [(match_parallel 0 "load_multiple_operation"
8428     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8429           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8430      (set (match_operand:SI 3 "gpc_reg_operand" "")
8431           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8432      (set (match_operand:SI 4 "gpc_reg_operand" "")
8433           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8434      (set (match_operand:SI 5 "gpc_reg_operand" "")
8435           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8436      (set (match_operand:SI 6 "gpc_reg_operand" "")
8437           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8438      (set (match_operand:SI 7 "gpc_reg_operand" "")
8439           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8440   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8441   "*
8442 { return rs6000_output_load_multiple (operands); }"
8443   [(set_attr "type" "load")
8444    (set_attr "update" "yes")
8445    (set_attr "indexed" "yes")
8446    (set_attr "length" "32")])
8448 (define_insn "*ldmsi5"
8449   [(match_parallel 0 "load_multiple_operation"
8450     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8451           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8452      (set (match_operand:SI 3 "gpc_reg_operand" "")
8453           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8454      (set (match_operand:SI 4 "gpc_reg_operand" "")
8455           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8456      (set (match_operand:SI 5 "gpc_reg_operand" "")
8457           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8458      (set (match_operand:SI 6 "gpc_reg_operand" "")
8459           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8460   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8461   "*
8462 { return rs6000_output_load_multiple (operands); }"
8463   [(set_attr "type" "load")
8464    (set_attr "update" "yes")
8465    (set_attr "indexed" "yes")
8466    (set_attr "length" "32")])
8468 (define_insn "*ldmsi4"
8469   [(match_parallel 0 "load_multiple_operation"
8470     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8471           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8472      (set (match_operand:SI 3 "gpc_reg_operand" "")
8473           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8474      (set (match_operand:SI 4 "gpc_reg_operand" "")
8475           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8476      (set (match_operand:SI 5 "gpc_reg_operand" "")
8477           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8478   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8479   "*
8480 { return rs6000_output_load_multiple (operands); }"
8481   [(set_attr "type" "load")
8482    (set_attr "update" "yes")
8483    (set_attr "indexed" "yes")
8484    (set_attr "length" "32")])
8486 (define_insn "*ldmsi3"
8487   [(match_parallel 0 "load_multiple_operation"
8488     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8489           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8490      (set (match_operand:SI 3 "gpc_reg_operand" "")
8491           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8492      (set (match_operand:SI 4 "gpc_reg_operand" "")
8493           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8494   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8495   "*
8496 { return rs6000_output_load_multiple (operands); }"
8497   [(set_attr "type" "load")
8498    (set_attr "update" "yes")
8499    (set_attr "indexed" "yes")
8500    (set_attr "length" "32")])
8502 (define_expand "store_multiple"
8503   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8504                           (match_operand:SI 1 "" ""))
8505                      (clobber (scratch:SI))
8506                      (use (match_operand:SI 2 "" ""))])]
8507   "TARGET_STRING && !TARGET_POWERPC64"
8508   "
8510   int regno;
8511   int count;
8512   rtx to;
8513   rtx op0;
8514   int i;
8516   /* Support only storing a constant number of fixed-point registers to
8517      memory and only bother with this if more than two; the machine
8518      doesn't support more than eight.  */
8519   if (GET_CODE (operands[2]) != CONST_INT
8520       || INTVAL (operands[2]) <= 2
8521       || INTVAL (operands[2]) > 8
8522       || GET_CODE (operands[0]) != MEM
8523       || GET_CODE (operands[1]) != REG
8524       || REGNO (operands[1]) >= 32)
8525     FAIL;
8527   count = INTVAL (operands[2]);
8528   regno = REGNO (operands[1]);
8530   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8531   to = force_reg (SImode, XEXP (operands[0], 0));
8532   op0 = replace_equiv_address (operands[0], to);
8534   XVECEXP (operands[3], 0, 0)
8535     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8536   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8537                                                  gen_rtx_SCRATCH (SImode));
8539   for (i = 1; i < count; i++)
8540     XVECEXP (operands[3], 0, i + 1)
8541       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8542                      gen_rtx_REG (SImode, regno + i));
8545 (define_insn "*stmsi8"
8546   [(match_parallel 0 "store_multiple_operation"
8547     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8548           (match_operand:SI 2 "gpc_reg_operand" "r"))
8549      (clobber (match_scratch:SI 3 "=X"))
8550      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8551           (match_operand:SI 4 "gpc_reg_operand" "r"))
8552      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8553           (match_operand:SI 5 "gpc_reg_operand" "r"))
8554      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8555           (match_operand:SI 6 "gpc_reg_operand" "r"))
8556      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8557           (match_operand:SI 7 "gpc_reg_operand" "r"))
8558      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8559           (match_operand:SI 8 "gpc_reg_operand" "r"))
8560      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8561           (match_operand:SI 9 "gpc_reg_operand" "r"))
8562      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8563           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8564   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8565   "stswi %2,%1,%O0"
8566   [(set_attr "type" "store")
8567    (set_attr "update" "yes")
8568    (set_attr "indexed" "yes")
8569    (set_attr "cell_micro" "always")])
8571 (define_insn "*stmsi7"
8572   [(match_parallel 0 "store_multiple_operation"
8573     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8574           (match_operand:SI 2 "gpc_reg_operand" "r"))
8575      (clobber (match_scratch:SI 3 "=X"))
8576      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8577           (match_operand:SI 4 "gpc_reg_operand" "r"))
8578      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8579           (match_operand:SI 5 "gpc_reg_operand" "r"))
8580      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8581           (match_operand:SI 6 "gpc_reg_operand" "r"))
8582      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8583           (match_operand:SI 7 "gpc_reg_operand" "r"))
8584      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8585           (match_operand:SI 8 "gpc_reg_operand" "r"))
8586      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8587           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8588   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8589   "stswi %2,%1,%O0"
8590   [(set_attr "type" "store")
8591    (set_attr "update" "yes")
8592    (set_attr "indexed" "yes")
8593    (set_attr "cell_micro" "always")])
8595 (define_insn "*stmsi6"
8596   [(match_parallel 0 "store_multiple_operation"
8597     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8598           (match_operand:SI 2 "gpc_reg_operand" "r"))
8599      (clobber (match_scratch:SI 3 "=X"))
8600      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8601           (match_operand:SI 4 "gpc_reg_operand" "r"))
8602      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8603           (match_operand:SI 5 "gpc_reg_operand" "r"))
8604      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8605           (match_operand:SI 6 "gpc_reg_operand" "r"))
8606      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8607           (match_operand:SI 7 "gpc_reg_operand" "r"))
8608      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8609           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8610   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8611   "stswi %2,%1,%O0"
8612   [(set_attr "type" "store")
8613    (set_attr "update" "yes")
8614    (set_attr "indexed" "yes")
8615    (set_attr "cell_micro" "always")])
8617 (define_insn "*stmsi5"
8618   [(match_parallel 0 "store_multiple_operation"
8619     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8620           (match_operand:SI 2 "gpc_reg_operand" "r"))
8621      (clobber (match_scratch:SI 3 "=X"))
8622      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8623           (match_operand:SI 4 "gpc_reg_operand" "r"))
8624      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8625           (match_operand:SI 5 "gpc_reg_operand" "r"))
8626      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8627           (match_operand:SI 6 "gpc_reg_operand" "r"))
8628      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8629           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8630   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8631   "stswi %2,%1,%O0"
8632   [(set_attr "type" "store")
8633    (set_attr "update" "yes")
8634    (set_attr "indexed" "yes")
8635    (set_attr "cell_micro" "always")])
8637 (define_insn "*stmsi4"
8638   [(match_parallel 0 "store_multiple_operation"
8639     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8640           (match_operand:SI 2 "gpc_reg_operand" "r"))
8641      (clobber (match_scratch:SI 3 "=X"))
8642      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8643           (match_operand:SI 4 "gpc_reg_operand" "r"))
8644      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8645           (match_operand:SI 5 "gpc_reg_operand" "r"))
8646      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8647           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8648   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8649   "stswi %2,%1,%O0"
8650   [(set_attr "type" "store")
8651    (set_attr "update" "yes")
8652    (set_attr "indexed" "yes")
8653    (set_attr "cell_micro" "always")])
8655 (define_insn "*stmsi3"
8656   [(match_parallel 0 "store_multiple_operation"
8657     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8658           (match_operand:SI 2 "gpc_reg_operand" "r"))
8659      (clobber (match_scratch:SI 3 "=X"))
8660      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8661           (match_operand:SI 4 "gpc_reg_operand" "r"))
8662      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8663           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8664   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8665   "stswi %2,%1,%O0"
8666   [(set_attr "type" "store")
8667    (set_attr "update" "yes")
8668    (set_attr "indexed" "yes")
8669    (set_attr "cell_micro" "always")])
8671 (define_expand "setmemsi"
8672   [(parallel [(set (match_operand:BLK 0 "" "")
8673                    (match_operand 2 "const_int_operand" ""))
8674               (use (match_operand:SI 1 "" ""))
8675               (use (match_operand:SI 3 "" ""))])]
8676   ""
8677   "
8679   /* If value to set is not zero, use the library routine.  */
8680   if (operands[2] != const0_rtx)
8681     FAIL;
8683   if (expand_block_clear (operands))
8684     DONE;
8685   else
8686     FAIL;
8689 ;; String/block compare insn.
8690 ;; Argument 0 is the target (result)
8691 ;; Argument 1 is the destination
8692 ;; Argument 2 is the source
8693 ;; Argument 3 is the length
8694 ;; Argument 4 is the alignment
8696 (define_expand "cmpmemsi"
8697   [(parallel [(set (match_operand:SI 0)
8698                (compare:SI (match_operand:BLK 1)
8699                            (match_operand:BLK 2)))
8700               (use (match_operand:SI 3))
8701               (use (match_operand:SI 4))])]
8702   ""
8704   if (expand_block_compare (operands))
8705     DONE;
8706   else  
8707     FAIL;
8710 ;; String/block move insn.
8711 ;; Argument 0 is the destination
8712 ;; Argument 1 is the source
8713 ;; Argument 2 is the length
8714 ;; Argument 3 is the alignment
8716 (define_expand "movmemsi"
8717   [(parallel [(set (match_operand:BLK 0 "" "")
8718                    (match_operand:BLK 1 "" ""))
8719               (use (match_operand:SI 2 "" ""))
8720               (use (match_operand:SI 3 "" ""))])]
8721   ""
8722   "
8724   if (expand_block_move (operands))
8725     DONE;
8726   else
8727     FAIL;
8730 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8731 ;; register allocator doesn't have a clue about allocating 8 word registers.
8732 ;; rD/rS = r5 is preferred, efficient form.
8733 (define_expand "movmemsi_8reg"
8734   [(parallel [(set (match_operand 0 "" "")
8735                    (match_operand 1 "" ""))
8736               (use (match_operand 2 "" ""))
8737               (use (match_operand 3 "" ""))
8738               (clobber (reg:SI  5))
8739               (clobber (reg:SI  6))
8740               (clobber (reg:SI  7))
8741               (clobber (reg:SI  8))
8742               (clobber (reg:SI  9))
8743               (clobber (reg:SI 10))
8744               (clobber (reg:SI 11))
8745               (clobber (reg:SI 12))
8746               (clobber (match_scratch:SI 4 ""))])]
8747   "TARGET_STRING"
8748   "")
8750 (define_insn ""
8751   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8752         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8753    (use (match_operand:SI 2 "immediate_operand" "i"))
8754    (use (match_operand:SI 3 "immediate_operand" "i"))
8755    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8756    (clobber (reg:SI  6))
8757    (clobber (reg:SI  7))
8758    (clobber (reg:SI  8))
8759    (clobber (reg:SI  9))
8760    (clobber (reg:SI 10))
8761    (clobber (reg:SI 11))
8762    (clobber (reg:SI 12))
8763    (clobber (match_scratch:SI 5 "=X"))]
8764   "TARGET_STRING
8765    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8766        || INTVAL (operands[2]) == 0)
8767    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8768    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8769    && REGNO (operands[4]) == 5"
8770   "lswi %4,%1,%2\;stswi %4,%0,%2"
8771   [(set_attr "type" "store")
8772    (set_attr "update" "yes")
8773    (set_attr "indexed" "yes")
8774    (set_attr "cell_micro" "always")
8775    (set_attr "length" "8")])
8777 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8778 ;; register allocator doesn't have a clue about allocating 6 word registers.
8779 ;; rD/rS = r5 is preferred, efficient form.
8780 (define_expand "movmemsi_6reg"
8781   [(parallel [(set (match_operand 0 "" "")
8782                    (match_operand 1 "" ""))
8783               (use (match_operand 2 "" ""))
8784               (use (match_operand 3 "" ""))
8785               (clobber (reg:SI  5))
8786               (clobber (reg:SI  6))
8787               (clobber (reg:SI  7))
8788               (clobber (reg:SI  8))
8789               (clobber (reg:SI  9))
8790               (clobber (reg:SI 10))
8791               (clobber (match_scratch:SI 4 ""))])]
8792   "TARGET_STRING"
8793   "")
8795 (define_insn ""
8796   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8797         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8798    (use (match_operand:SI 2 "immediate_operand" "i"))
8799    (use (match_operand:SI 3 "immediate_operand" "i"))
8800    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8801    (clobber (reg:SI  6))
8802    (clobber (reg:SI  7))
8803    (clobber (reg:SI  8))
8804    (clobber (reg:SI  9))
8805    (clobber (reg:SI 10))
8806    (clobber (match_scratch:SI 5 "=X"))]
8807   "TARGET_STRING
8808    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8809    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8810    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8811    && REGNO (operands[4]) == 5"
8812   "lswi %4,%1,%2\;stswi %4,%0,%2"
8813   [(set_attr "type" "store")
8814    (set_attr "update" "yes")
8815    (set_attr "indexed" "yes")
8816    (set_attr "cell_micro" "always")
8817    (set_attr "length" "8")])
8819 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8820 ;; problems with TImode.
8821 ;; rD/rS = r5 is preferred, efficient form.
8822 (define_expand "movmemsi_4reg"
8823   [(parallel [(set (match_operand 0 "" "")
8824                    (match_operand 1 "" ""))
8825               (use (match_operand 2 "" ""))
8826               (use (match_operand 3 "" ""))
8827               (clobber (reg:SI 5))
8828               (clobber (reg:SI 6))
8829               (clobber (reg:SI 7))
8830               (clobber (reg:SI 8))
8831               (clobber (match_scratch:SI 4 ""))])]
8832   "TARGET_STRING"
8833   "")
8835 (define_insn ""
8836   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8837         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8838    (use (match_operand:SI 2 "immediate_operand" "i"))
8839    (use (match_operand:SI 3 "immediate_operand" "i"))
8840    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8841    (clobber (reg:SI 6))
8842    (clobber (reg:SI 7))
8843    (clobber (reg:SI 8))
8844    (clobber (match_scratch:SI 5 "=X"))]
8845   "TARGET_STRING
8846    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8847    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8848    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8849    && REGNO (operands[4]) == 5"
8850   "lswi %4,%1,%2\;stswi %4,%0,%2"
8851   [(set_attr "type" "store")
8852    (set_attr "update" "yes")
8853    (set_attr "indexed" "yes")
8854    (set_attr "cell_micro" "always")
8855    (set_attr "length" "8")])
8857 ;; Move up to 8 bytes at a time.
8858 (define_expand "movmemsi_2reg"
8859   [(parallel [(set (match_operand 0 "" "")
8860                    (match_operand 1 "" ""))
8861               (use (match_operand 2 "" ""))
8862               (use (match_operand 3 "" ""))
8863               (clobber (match_scratch:DI 4 ""))
8864               (clobber (match_scratch:SI 5 ""))])]
8865   "TARGET_STRING && ! TARGET_POWERPC64"
8866   "")
8868 (define_insn ""
8869   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8870         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8871    (use (match_operand:SI 2 "immediate_operand" "i"))
8872    (use (match_operand:SI 3 "immediate_operand" "i"))
8873    (clobber (match_scratch:DI 4 "=&r"))
8874    (clobber (match_scratch:SI 5 "=X"))]
8875   "TARGET_STRING && ! TARGET_POWERPC64
8876    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8877   "lswi %4,%1,%2\;stswi %4,%0,%2"
8878   [(set_attr "type" "store")
8879    (set_attr "update" "yes")
8880    (set_attr "indexed" "yes")
8881    (set_attr "cell_micro" "always")
8882    (set_attr "length" "8")])
8884 ;; Move up to 4 bytes at a time.
8885 (define_expand "movmemsi_1reg"
8886   [(parallel [(set (match_operand 0 "" "")
8887                    (match_operand 1 "" ""))
8888               (use (match_operand 2 "" ""))
8889               (use (match_operand 3 "" ""))
8890               (clobber (match_scratch:SI 4 ""))
8891               (clobber (match_scratch:SI 5 ""))])]
8892   "TARGET_STRING"
8893   "")
8895 (define_insn ""
8896   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8897         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8898    (use (match_operand:SI 2 "immediate_operand" "i"))
8899    (use (match_operand:SI 3 "immediate_operand" "i"))
8900    (clobber (match_scratch:SI 4 "=&r"))
8901    (clobber (match_scratch:SI 5 "=X"))]
8902   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8903   "lswi %4,%1,%2\;stswi %4,%0,%2"
8904   [(set_attr "type" "store")
8905    (set_attr "update" "yes")
8906    (set_attr "indexed" "yes")
8907    (set_attr "cell_micro" "always")
8908    (set_attr "length" "8")])
8910 ;; Define insns that do load or store with update.  Some of these we can
8911 ;; get by using pre-decrement or pre-increment, but the hardware can also
8912 ;; do cases where the increment is not the size of the object.
8914 ;; In all these cases, we use operands 0 and 1 for the register being
8915 ;; incremented because those are the operands that local-alloc will
8916 ;; tie and these are the pair most likely to be tieable (and the ones
8917 ;; that will benefit the most).
8919 (define_insn "*movdi_update1"
8920   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8921         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8922                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8923    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8924         (plus:DI (match_dup 1) (match_dup 2)))]
8925   "TARGET_POWERPC64 && TARGET_UPDATE
8926    && (!avoiding_indexed_address_p (DImode)
8927        || !gpc_reg_operand (operands[2], DImode))"
8928   "@
8929    ldux %3,%0,%2
8930    ldu %3,%2(%0)"
8931   [(set_attr "type" "load")
8932    (set_attr "update" "yes")
8933    (set_attr "indexed" "yes,no")])
8935 (define_insn "movdi_<mode>_update"
8936   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8937                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8938         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8939    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8940         (plus:P (match_dup 1) (match_dup 2)))]
8941   "TARGET_POWERPC64 && TARGET_UPDATE
8942    && (!avoiding_indexed_address_p (Pmode)
8943        || !gpc_reg_operand (operands[2], Pmode)
8944        || (REG_P (operands[0])
8945            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8946   "@
8947    stdux %3,%0,%2
8948    stdu %3,%2(%0)"
8949   [(set_attr "type" "store")
8950    (set_attr "update" "yes")
8951    (set_attr "indexed" "yes,no")])
8953 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8954 ;; needed for stack allocation, even if the user passes -mno-update.
8955 (define_insn "movdi_<mode>_update_stack"
8956   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8957                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8958         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8959    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8960         (plus:P (match_dup 1) (match_dup 2)))]
8961   "TARGET_POWERPC64"
8962   "@
8963    stdux %3,%0,%2
8964    stdu %3,%2(%0)"
8965   [(set_attr "type" "store")
8966    (set_attr "update" "yes")
8967    (set_attr "indexed" "yes,no")])
8969 (define_insn "*movsi_update1"
8970   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8971         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8972                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8973    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8974         (plus:SI (match_dup 1) (match_dup 2)))]
8975   "TARGET_UPDATE
8976    && (!avoiding_indexed_address_p (SImode)
8977        || !gpc_reg_operand (operands[2], SImode))"
8978   "@
8979    lwzux %3,%0,%2
8980    lwzu %3,%2(%0)"
8981   [(set_attr "type" "load")
8982    (set_attr "update" "yes")
8983    (set_attr "indexed" "yes,no")])
8985 (define_insn "*movsi_update2"
8986   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8987         (sign_extend:DI
8988          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8989                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8990    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8991         (plus:DI (match_dup 1) (match_dup 2)))]
8992   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8993    && !avoiding_indexed_address_p (DImode)"
8994   "lwaux %3,%0,%2"
8995   [(set_attr "type" "load")
8996    (set_attr "sign_extend" "yes")
8997    (set_attr "update" "yes")
8998    (set_attr "indexed" "yes")])
9000 (define_insn "movsi_update"
9001   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9002                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9003         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9004    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9005         (plus:SI (match_dup 1) (match_dup 2)))]
9006   "TARGET_UPDATE
9007    && (!avoiding_indexed_address_p (SImode)
9008        || !gpc_reg_operand (operands[2], SImode)
9009        || (REG_P (operands[0])
9010            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9011   "@
9012    stwux %3,%0,%2
9013    stwu %3,%2(%0)"
9014   [(set_attr "type" "store")
9015    (set_attr "update" "yes")
9016    (set_attr "indexed" "yes,no")])
9018 ;; This is an unconditional pattern; needed for stack allocation, even
9019 ;; if the user passes -mno-update.
9020 (define_insn "movsi_update_stack"
9021   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9022                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9023         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9024    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9025         (plus:SI (match_dup 1) (match_dup 2)))]
9026   ""
9027   "@
9028    stwux %3,%0,%2
9029    stwu %3,%2(%0)"
9030   [(set_attr "type" "store")
9031    (set_attr "update" "yes")
9032    (set_attr "indexed" "yes,no")])
9034 (define_insn "*movhi_update1"
9035   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9036         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9037                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9038    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9039         (plus:SI (match_dup 1) (match_dup 2)))]
9040   "TARGET_UPDATE
9041    && (!avoiding_indexed_address_p (SImode)
9042        || !gpc_reg_operand (operands[2], SImode))"
9043   "@
9044    lhzux %3,%0,%2
9045    lhzu %3,%2(%0)"
9046   [(set_attr "type" "load")
9047    (set_attr "update" "yes")
9048    (set_attr "indexed" "yes,no")])
9050 (define_insn "*movhi_update2"
9051   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9052         (zero_extend:SI
9053          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9054                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9055    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9056         (plus:SI (match_dup 1) (match_dup 2)))]
9057   "TARGET_UPDATE
9058    && (!avoiding_indexed_address_p (SImode)
9059        || !gpc_reg_operand (operands[2], SImode))"
9060   "@
9061    lhzux %3,%0,%2
9062    lhzu %3,%2(%0)"
9063   [(set_attr "type" "load")
9064    (set_attr "update" "yes")
9065    (set_attr "indexed" "yes,no")])
9067 (define_insn "*movhi_update3"
9068   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9069         (sign_extend:SI
9070          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9071                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9072    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9073         (plus:SI (match_dup 1) (match_dup 2)))]
9074   "TARGET_UPDATE && rs6000_gen_cell_microcode
9075    && (!avoiding_indexed_address_p (SImode)
9076        || !gpc_reg_operand (operands[2], SImode))"
9077   "@
9078    lhaux %3,%0,%2
9079    lhau %3,%2(%0)"
9080   [(set_attr "type" "load")
9081    (set_attr "sign_extend" "yes")
9082    (set_attr "update" "yes")
9083    (set_attr "indexed" "yes,no")])
9085 (define_insn "*movhi_update4"
9086   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9087                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9088         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9089    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9090         (plus:SI (match_dup 1) (match_dup 2)))]
9091   "TARGET_UPDATE
9092    && (!avoiding_indexed_address_p (SImode)
9093        || !gpc_reg_operand (operands[2], SImode))"
9094   "@
9095    sthux %3,%0,%2
9096    sthu %3,%2(%0)"
9097   [(set_attr "type" "store")
9098    (set_attr "update" "yes")
9099    (set_attr "indexed" "yes,no")])
9101 (define_insn "*movqi_update1"
9102   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9103         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9104                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9105    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9106         (plus:SI (match_dup 1) (match_dup 2)))]
9107   "TARGET_UPDATE
9108    && (!avoiding_indexed_address_p (SImode)
9109        || !gpc_reg_operand (operands[2], SImode))"
9110   "@
9111    lbzux %3,%0,%2
9112    lbzu %3,%2(%0)"
9113   [(set_attr "type" "load")
9114    (set_attr "update" "yes")
9115    (set_attr "indexed" "yes,no")])
9117 (define_insn "*movqi_update2"
9118   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9119         (zero_extend:SI
9120          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9121                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9122    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9123         (plus:SI (match_dup 1) (match_dup 2)))]
9124   "TARGET_UPDATE
9125    && (!avoiding_indexed_address_p (SImode)
9126        || !gpc_reg_operand (operands[2], SImode))"
9127   "@
9128    lbzux %3,%0,%2
9129    lbzu %3,%2(%0)"
9130   [(set_attr "type" "load")
9131    (set_attr "update" "yes")
9132    (set_attr "indexed" "yes,no")])
9134 (define_insn "*movqi_update3"
9135   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9136                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9137         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9138    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9139         (plus:SI (match_dup 1) (match_dup 2)))]
9140   "TARGET_UPDATE
9141    && (!avoiding_indexed_address_p (SImode)
9142        || !gpc_reg_operand (operands[2], SImode))"
9143   "@
9144    stbux %3,%0,%2
9145    stbu %3,%2(%0)"
9146   [(set_attr "type" "store")
9147    (set_attr "update" "yes")
9148    (set_attr "indexed" "yes,no")])
9150 (define_insn "*movsf_update1"
9151   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9152         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9153                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9154    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9155         (plus:SI (match_dup 1) (match_dup 2)))]
9156   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9157    && (!avoiding_indexed_address_p (SImode)
9158        || !gpc_reg_operand (operands[2], SImode))"
9159   "@
9160    lfsux %3,%0,%2
9161    lfsu %3,%2(%0)"
9162   [(set_attr "type" "fpload")
9163    (set_attr "update" "yes")
9164    (set_attr "indexed" "yes,no")])
9166 (define_insn "*movsf_update2"
9167   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9168                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9169         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9170    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9171         (plus:SI (match_dup 1) (match_dup 2)))]
9172   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9173    && (!avoiding_indexed_address_p (SImode)
9174        || !gpc_reg_operand (operands[2], SImode))"
9175   "@
9176    stfsux %3,%0,%2
9177    stfsu %3,%2(%0)"
9178   [(set_attr "type" "fpstore")
9179    (set_attr "update" "yes")
9180    (set_attr "indexed" "yes,no")])
9182 (define_insn "*movsf_update3"
9183   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9184         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9185                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9186    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9187         (plus:SI (match_dup 1) (match_dup 2)))]
9188   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9189    && (!avoiding_indexed_address_p (SImode)
9190        || !gpc_reg_operand (operands[2], SImode))"
9191   "@
9192    lwzux %3,%0,%2
9193    lwzu %3,%2(%0)"
9194   [(set_attr "type" "load")
9195    (set_attr "update" "yes")
9196    (set_attr "indexed" "yes,no")])
9198 (define_insn "*movsf_update4"
9199   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9200                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9201         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9202    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9203         (plus:SI (match_dup 1) (match_dup 2)))]
9204   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9205    && (!avoiding_indexed_address_p (SImode)
9206        || !gpc_reg_operand (operands[2], SImode))"
9207   "@
9208    stwux %3,%0,%2
9209    stwu %3,%2(%0)"
9210   [(set_attr "type" "store")
9211    (set_attr "update" "yes")
9212    (set_attr "indexed" "yes,no")])
9214 (define_insn "*movdf_update1"
9215   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9216         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9217                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9218    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9219         (plus:SI (match_dup 1) (match_dup 2)))]
9220   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9221    && (!avoiding_indexed_address_p (SImode)
9222        || !gpc_reg_operand (operands[2], SImode))"
9223   "@
9224    lfdux %3,%0,%2
9225    lfdu %3,%2(%0)"
9226   [(set_attr "type" "fpload")
9227    (set_attr "update" "yes")
9228    (set_attr "indexed" "yes,no")
9229    (set_attr "size" "64")])
9231 (define_insn "*movdf_update2"
9232   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9233                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9234         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9235    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9236         (plus:SI (match_dup 1) (match_dup 2)))]
9237   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9238    && (!avoiding_indexed_address_p (SImode)
9239        || !gpc_reg_operand (operands[2], SImode))"
9240   "@
9241    stfdux %3,%0,%2
9242    stfdu %3,%2(%0)"
9243   [(set_attr "type" "fpstore")
9244    (set_attr "update" "yes")
9245    (set_attr "indexed" "yes,no")])
9248 ;; After inserting conditional returns we can sometimes have
9249 ;; unnecessary register moves.  Unfortunately we cannot have a
9250 ;; modeless peephole here, because some single SImode sets have early
9251 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9252 ;; sequences, using get_attr_length here will smash the operands
9253 ;; array.  Neither is there an early_cobbler_p predicate.
9254 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9255 ;; Also this optimization interferes with scalars going into
9256 ;; altivec registers (the code does reloading through the FPRs).
9257 (define_peephole2
9258   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9259         (match_operand:DF 1 "any_operand" ""))
9260    (set (match_operand:DF 2 "gpc_reg_operand" "")
9261         (match_dup 0))]
9262   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9263    && !TARGET_UPPER_REGS_DF
9264    && peep2_reg_dead_p (2, operands[0])"
9265   [(set (match_dup 2) (match_dup 1))])
9267 (define_peephole2
9268   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9269         (match_operand:SF 1 "any_operand" ""))
9270    (set (match_operand:SF 2 "gpc_reg_operand" "")
9271         (match_dup 0))]
9272   "!TARGET_UPPER_REGS_SF
9273    && peep2_reg_dead_p (2, operands[0])"
9274   [(set (match_dup 2) (match_dup 1))])
9277 ;; TLS support.
9279 ;; Mode attributes for different ABIs.
9280 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9281 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9282 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9283 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9285 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9286   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9287         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9288               (match_operand 4 "" "g")))
9289    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9290                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9291                    UNSPEC_TLSGD)
9292    (clobber (reg:SI LR_REGNO))]
9293   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9295   if (TARGET_CMODEL != CMODEL_SMALL)
9296     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9297            "bl %z3\;nop";
9298   else
9299     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9301   "&& TARGET_TLS_MARKERS"
9302   [(set (match_dup 0)
9303         (unspec:TLSmode [(match_dup 1)
9304                          (match_dup 2)]
9305                         UNSPEC_TLSGD))
9306    (parallel [(set (match_dup 0)
9307                    (call (mem:TLSmode (match_dup 3))
9308                          (match_dup 4)))
9309               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9310               (clobber (reg:SI LR_REGNO))])]
9311   ""
9312   [(set_attr "type" "two")
9313    (set (attr "length")
9314      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9315                    (const_int 16)
9316                    (const_int 12)))])
9318 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9319   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9320         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9321               (match_operand 4 "" "g")))
9322    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9323                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9324                    UNSPEC_TLSGD)
9325    (clobber (reg:SI LR_REGNO))]
9326   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9328   if (flag_pic)
9329     {
9330       if (TARGET_SECURE_PLT && flag_pic == 2)
9331         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9332       else
9333         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9334     }
9335   else
9336     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9338   "&& TARGET_TLS_MARKERS"
9339   [(set (match_dup 0)
9340         (unspec:TLSmode [(match_dup 1)
9341                          (match_dup 2)]
9342                         UNSPEC_TLSGD))
9343    (parallel [(set (match_dup 0)
9344                    (call (mem:TLSmode (match_dup 3))
9345                          (match_dup 4)))
9346               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9347               (clobber (reg:SI LR_REGNO))])]
9348   ""
9349   [(set_attr "type" "two")
9350    (set_attr "length" "8")])
9352 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9353   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9354         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9355                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9356                         UNSPEC_TLSGD))]
9357   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9358   "addi %0,%1,%2@got@tlsgd"
9359   "&& TARGET_CMODEL != CMODEL_SMALL"
9360   [(set (match_dup 3)
9361         (high:TLSmode
9362             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9363    (set (match_dup 0)
9364         (lo_sum:TLSmode (match_dup 3)
9365             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9366   "
9368   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9370   [(set (attr "length")
9371      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9372                    (const_int 8)
9373                    (const_int 4)))])
9375 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9376   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9377      (high:TLSmode
9378        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9379                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9380                        UNSPEC_TLSGD)))]
9381   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9382   "addis %0,%1,%2@got@tlsgd@ha"
9383   [(set_attr "length" "4")])
9385 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9386   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9387      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9388        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9389                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9390                        UNSPEC_TLSGD)))]
9391   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9392   "addi %0,%1,%2@got@tlsgd@l"
9393   [(set_attr "length" "4")])
9395 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9396   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9397         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9398               (match_operand 2 "" "g")))
9399    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9400                    UNSPEC_TLSGD)
9401    (clobber (reg:SI LR_REGNO))]
9402   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9403    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9404   "bl %z1(%3@tlsgd)\;nop"
9405   [(set_attr "type" "branch")
9406    (set_attr "length" "8")])
9408 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9409   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9410         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9411               (match_operand 2 "" "g")))
9412    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9413                    UNSPEC_TLSGD)
9414    (clobber (reg:SI LR_REGNO))]
9415   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9417   if (flag_pic)
9418     {
9419       if (TARGET_SECURE_PLT && flag_pic == 2)
9420         return "bl %z1+32768(%3@tlsgd)@plt";
9421       return "bl %z1(%3@tlsgd)@plt";
9422     }
9423   return "bl %z1(%3@tlsgd)";
9425   [(set_attr "type" "branch")
9426    (set_attr "length" "4")])
9428 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9429   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9430         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9431               (match_operand 3 "" "g")))
9432    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9433                    UNSPEC_TLSLD)
9434    (clobber (reg:SI LR_REGNO))]
9435   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9437   if (TARGET_CMODEL != CMODEL_SMALL)
9438     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9439            "bl %z2\;nop";
9440   else
9441     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9443   "&& TARGET_TLS_MARKERS"
9444   [(set (match_dup 0)
9445         (unspec:TLSmode [(match_dup 1)]
9446                         UNSPEC_TLSLD))
9447    (parallel [(set (match_dup 0)
9448                    (call (mem:TLSmode (match_dup 2))
9449                          (match_dup 3)))
9450               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9451               (clobber (reg:SI LR_REGNO))])]
9452   ""
9453   [(set_attr "type" "two")
9454    (set (attr "length")
9455      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9456                    (const_int 16)
9457                    (const_int 12)))])
9459 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9460   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9461         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9462               (match_operand 3 "" "g")))
9463    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9464                    UNSPEC_TLSLD)
9465    (clobber (reg:SI LR_REGNO))]
9466   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9468   if (flag_pic)
9469     {
9470       if (TARGET_SECURE_PLT && flag_pic == 2)
9471         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9472       else
9473         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9474     }
9475   else
9476     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9478   "&& TARGET_TLS_MARKERS"
9479   [(set (match_dup 0)
9480         (unspec:TLSmode [(match_dup 1)]
9481                         UNSPEC_TLSLD))
9482    (parallel [(set (match_dup 0)
9483                    (call (mem:TLSmode (match_dup 2))
9484                          (match_dup 3)))
9485               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9486               (clobber (reg:SI LR_REGNO))])]
9487   ""
9488   [(set_attr "length" "8")])
9490 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9491   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9492         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9493                         UNSPEC_TLSLD))]
9494   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9495   "addi %0,%1,%&@got@tlsld"
9496   "&& TARGET_CMODEL != CMODEL_SMALL"
9497   [(set (match_dup 2)
9498         (high:TLSmode
9499             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9500    (set (match_dup 0)
9501         (lo_sum:TLSmode (match_dup 2)
9502             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9503   "
9505   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9507   [(set (attr "length")
9508      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9509                    (const_int 8)
9510                    (const_int 4)))])
9512 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9513   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9514      (high:TLSmode
9515        (unspec:TLSmode [(const_int 0)
9516                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9517                        UNSPEC_TLSLD)))]
9518   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9519   "addis %0,%1,%&@got@tlsld@ha"
9520   [(set_attr "length" "4")])
9522 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9523   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9524      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9525        (unspec:TLSmode [(const_int 0)
9526                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9527                        UNSPEC_TLSLD)))]
9528   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9529   "addi %0,%1,%&@got@tlsld@l"
9530   [(set_attr "length" "4")])
9532 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9533   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9535               (match_operand 2 "" "g")))
9536    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9537    (clobber (reg:SI LR_REGNO))]
9538   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9539    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9540   "bl %z1(%&@tlsld)\;nop"
9541   [(set_attr "type" "branch")
9542    (set_attr "length" "8")])
9544 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9545   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9546         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9547               (match_operand 2 "" "g")))
9548    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9549    (clobber (reg:SI LR_REGNO))]
9550   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9552   if (flag_pic)
9553     {
9554       if (TARGET_SECURE_PLT && flag_pic == 2)
9555         return "bl %z1+32768(%&@tlsld)@plt";
9556       return "bl %z1(%&@tlsld)@plt";
9557     }
9558   return "bl %z1(%&@tlsld)";
9560   [(set_attr "type" "branch")
9561    (set_attr "length" "4")])
9563 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9564   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9565         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9566                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9567                         UNSPEC_TLSDTPREL))]
9568   "HAVE_AS_TLS"
9569   "addi %0,%1,%2@dtprel")
9571 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9572   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9573         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9574                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9575                         UNSPEC_TLSDTPRELHA))]
9576   "HAVE_AS_TLS"
9577   "addis %0,%1,%2@dtprel@ha")
9579 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9580   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9581         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9582                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9583                         UNSPEC_TLSDTPRELLO))]
9584   "HAVE_AS_TLS"
9585   "addi %0,%1,%2@dtprel@l")
9587 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9588   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9589         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9590                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9591                         UNSPEC_TLSGOTDTPREL))]
9592   "HAVE_AS_TLS"
9593   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9594   "&& TARGET_CMODEL != CMODEL_SMALL"
9595   [(set (match_dup 3)
9596         (high:TLSmode
9597             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9598    (set (match_dup 0)
9599         (lo_sum:TLSmode (match_dup 3)
9600             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9601   "
9603   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9605   [(set (attr "length")
9606      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9607                    (const_int 8)
9608                    (const_int 4)))])
9610 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9611   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9612      (high:TLSmode
9613        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9614                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9615                        UNSPEC_TLSGOTDTPREL)))]
9616   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9617   "addis %0,%1,%2@got@dtprel@ha"
9618   [(set_attr "length" "4")])
9620 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9621   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9622      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9623          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9624                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9625                          UNSPEC_TLSGOTDTPREL)))]
9626   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9627   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9628   [(set_attr "length" "4")])
9630 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9631   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9632         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9633                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9634                         UNSPEC_TLSTPREL))]
9635   "HAVE_AS_TLS"
9636   "addi %0,%1,%2@tprel")
9638 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9639   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9640         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9641                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9642                         UNSPEC_TLSTPRELHA))]
9643   "HAVE_AS_TLS"
9644   "addis %0,%1,%2@tprel@ha")
9646 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9647   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9648         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9649                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9650                         UNSPEC_TLSTPRELLO))]
9651   "HAVE_AS_TLS"
9652   "addi %0,%1,%2@tprel@l")
9654 ;; "b" output constraint here and on tls_tls input to support linker tls
9655 ;; optimization.  The linker may edit the instructions emitted by a
9656 ;; tls_got_tprel/tls_tls pair to addis,addi.
9657 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9658   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9659         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9660                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9661                         UNSPEC_TLSGOTTPREL))]
9662   "HAVE_AS_TLS"
9663   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9664   "&& TARGET_CMODEL != CMODEL_SMALL"
9665   [(set (match_dup 3)
9666         (high:TLSmode
9667             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9668    (set (match_dup 0)
9669         (lo_sum:TLSmode (match_dup 3)
9670             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9671   "
9673   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9675   [(set (attr "length")
9676      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9677                    (const_int 8)
9678                    (const_int 4)))])
9680 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9681   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9682      (high:TLSmode
9683        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9684                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9685                        UNSPEC_TLSGOTTPREL)))]
9686   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9687   "addis %0,%1,%2@got@tprel@ha"
9688   [(set_attr "length" "4")])
9690 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9691   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9692      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9693          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9694                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9695                          UNSPEC_TLSGOTTPREL)))]
9696   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9697   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9698   [(set_attr "length" "4")])
9700 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9701   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9702         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9703                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9704                         UNSPEC_TLSTLS))]
9705   "TARGET_ELF && HAVE_AS_TLS"
9706   "add %0,%1,%2@tls")
9708 (define_expand "tls_get_tpointer"
9709   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9710         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9711   "TARGET_XCOFF && HAVE_AS_TLS"
9712   "
9714   emit_insn (gen_tls_get_tpointer_internal ());
9715   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9716   DONE;
9719 (define_insn "tls_get_tpointer_internal"
9720   [(set (reg:SI 3)
9721         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9722    (clobber (reg:SI LR_REGNO))]
9723   "TARGET_XCOFF && HAVE_AS_TLS"
9724   "bla __get_tpointer")
9726 (define_expand "tls_get_addr<mode>"
9727   [(set (match_operand:P 0 "gpc_reg_operand" "")
9728         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9729                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9730   "TARGET_XCOFF && HAVE_AS_TLS"
9731   "
9733   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9734   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9735   emit_insn (gen_tls_get_addr_internal<mode> ());
9736   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9737   DONE;
9740 (define_insn "tls_get_addr_internal<mode>"
9741   [(set (reg:P 3)
9742         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9743    (clobber (reg:P 0))
9744    (clobber (reg:P 4))
9745    (clobber (reg:P 5))
9746    (clobber (reg:P 11))
9747    (clobber (reg:CC CR0_REGNO))
9748    (clobber (reg:P LR_REGNO))]
9749   "TARGET_XCOFF && HAVE_AS_TLS"
9750   "bla __tls_get_addr")
9752 ;; Next come insns related to the calling sequence.
9754 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9755 ;; We move the back-chain and decrement the stack pointer.
9757 (define_expand "allocate_stack"
9758   [(set (match_operand 0 "gpc_reg_operand" "")
9759         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9760    (set (reg 1)
9761         (minus (reg 1) (match_dup 1)))]
9762   ""
9763   "
9764 { rtx chain = gen_reg_rtx (Pmode);
9765   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9766   rtx neg_op0;
9767   rtx insn, par, set, mem;
9769   emit_move_insn (chain, stack_bot);
9771   /* Check stack bounds if necessary.  */
9772   if (crtl->limit_stack)
9773     {
9774       rtx available;
9775       available = expand_binop (Pmode, sub_optab,
9776                                 stack_pointer_rtx, stack_limit_rtx,
9777                                 NULL_RTX, 1, OPTAB_WIDEN);
9778       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9779     }
9781   if (GET_CODE (operands[1]) != CONST_INT
9782       || INTVAL (operands[1]) < -32767
9783       || INTVAL (operands[1]) > 32768)
9784     {
9785       neg_op0 = gen_reg_rtx (Pmode);
9786       if (TARGET_32BIT)
9787         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9788       else
9789         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9790     }
9791   else
9792     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9794   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9795                                        : gen_movdi_di_update_stack))
9796                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9797                          chain));
9798   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9799      it now and set the alias set/attributes. The above gen_*_update
9800      calls will generate a PARALLEL with the MEM set being the first
9801      operation. */
9802   par = PATTERN (insn);
9803   gcc_assert (GET_CODE (par) == PARALLEL);
9804   set = XVECEXP (par, 0, 0);
9805   gcc_assert (GET_CODE (set) == SET);
9806   mem = SET_DEST (set);
9807   gcc_assert (MEM_P (mem));
9808   MEM_NOTRAP_P (mem) = 1;
9809   set_mem_alias_set (mem, get_frame_alias_set ());
9811   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9812   DONE;
9815 ;; These patterns say how to save and restore the stack pointer.  We need not
9816 ;; save the stack pointer at function level since we are careful to
9817 ;; preserve the backchain.  At block level, we have to restore the backchain
9818 ;; when we restore the stack pointer.
9820 ;; For nonlocal gotos, we must save both the stack pointer and its
9821 ;; backchain and restore both.  Note that in the nonlocal case, the
9822 ;; save area is a memory location.
9824 (define_expand "save_stack_function"
9825   [(match_operand 0 "any_operand" "")
9826    (match_operand 1 "any_operand" "")]
9827   ""
9828   "DONE;")
9830 (define_expand "restore_stack_function"
9831   [(match_operand 0 "any_operand" "")
9832    (match_operand 1 "any_operand" "")]
9833   ""
9834   "DONE;")
9836 ;; Adjust stack pointer (op0) to a new value (op1).
9837 ;; First copy old stack backchain to new location, and ensure that the
9838 ;; scheduler won't reorder the sp assignment before the backchain write.
9839 (define_expand "restore_stack_block"
9840   [(set (match_dup 2) (match_dup 3))
9841    (set (match_dup 4) (match_dup 2))
9842    (match_dup 5)
9843    (set (match_operand 0 "register_operand" "")
9844         (match_operand 1 "register_operand" ""))]
9845   ""
9846   "
9848   rtvec p;
9850   operands[1] = force_reg (Pmode, operands[1]);
9851   operands[2] = gen_reg_rtx (Pmode);
9852   operands[3] = gen_frame_mem (Pmode, operands[0]);
9853   operands[4] = gen_frame_mem (Pmode, operands[1]);
9854   p = rtvec_alloc (1);
9855   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9856                                   const0_rtx);
9857   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9860 (define_expand "save_stack_nonlocal"
9861   [(set (match_dup 3) (match_dup 4))
9862    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9863    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9864   ""
9865   "
9867   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9869   /* Copy the backchain to the first word, sp to the second.  */
9870   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9871   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9872   operands[3] = gen_reg_rtx (Pmode);
9873   operands[4] = gen_frame_mem (Pmode, operands[1]);
9876 (define_expand "restore_stack_nonlocal"
9877   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9878    (set (match_dup 3) (match_dup 4))
9879    (set (match_dup 5) (match_dup 2))
9880    (match_dup 6)
9881    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9882   ""
9883   "
9885   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9886   rtvec p;
9888   /* Restore the backchain from the first word, sp from the second.  */
9889   operands[2] = gen_reg_rtx (Pmode);
9890   operands[3] = gen_reg_rtx (Pmode);
9891   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9892   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9893   operands[5] = gen_frame_mem (Pmode, operands[3]);
9894   p = rtvec_alloc (1);
9895   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9896                                   const0_rtx);
9897   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9900 ;; TOC register handling.
9902 ;; Code to initialize the TOC register...
9904 (define_insn "load_toc_aix_si"
9905   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9906                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9907               (use (reg:SI 2))])]
9908   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9909   "*
9911   char buf[30];
9912   extern int need_toc_init;
9913   need_toc_init = 1;
9914   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9915   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9916   operands[2] = gen_rtx_REG (Pmode, 2);
9917   return \"lwz %0,%1(%2)\";
9919   [(set_attr "type" "load")
9920    (set_attr "update" "no")
9921    (set_attr "indexed" "no")])
9923 (define_insn "load_toc_aix_di"
9924   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9925                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9926               (use (reg:DI 2))])]
9927   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9928   "*
9930   char buf[30];
9931   extern int need_toc_init;
9932   need_toc_init = 1;
9933   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9934                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9935   if (TARGET_ELF)
9936     strcat (buf, \"@toc\");
9937   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9938   operands[2] = gen_rtx_REG (Pmode, 2);
9939   return \"ld %0,%1(%2)\";
9941   [(set_attr "type" "load")
9942    (set_attr "update" "no")
9943    (set_attr "indexed" "no")])
9945 (define_insn "load_toc_v4_pic_si"
9946   [(set (reg:SI LR_REGNO)
9947         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9948   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9949   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9950   [(set_attr "type" "branch")
9951    (set_attr "length" "4")])
9953 (define_expand "load_toc_v4_PIC_1"
9954   [(parallel [(set (reg:SI LR_REGNO)
9955                    (match_operand:SI 0 "immediate_operand" "s"))
9956               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9957   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9958    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9959   "")
9961 (define_insn "load_toc_v4_PIC_1_normal"
9962   [(set (reg:SI LR_REGNO)
9963         (match_operand:SI 0 "immediate_operand" "s"))
9964    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9965   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9966    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9967   "bcl 20,31,%0\\n%0:"
9968   [(set_attr "type" "branch")
9969    (set_attr "length" "4")
9970    (set_attr "cannot_copy" "yes")])
9972 (define_insn "load_toc_v4_PIC_1_476"
9973   [(set (reg:SI LR_REGNO)
9974         (match_operand:SI 0 "immediate_operand" "s"))
9975    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9976   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9977    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9978   "*
9980   char name[32];
9981   static char templ[32];
9983   get_ppc476_thunk_name (name);
9984   sprintf (templ, \"bl %s\\n%%0:\", name);
9985   return templ;
9987   [(set_attr "type" "branch")
9988    (set_attr "length" "4")
9989    (set_attr "cannot_copy" "yes")])
9991 (define_expand "load_toc_v4_PIC_1b"
9992   [(parallel [(set (reg:SI LR_REGNO)
9993                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9994                                (label_ref (match_operand 1 "" ""))]
9995                            UNSPEC_TOCPTR))
9996               (match_dup 1)])]
9997   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9998   "")
10000 (define_insn "load_toc_v4_PIC_1b_normal"
10001   [(set (reg:SI LR_REGNO)
10002         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10003                     (label_ref (match_operand 1 "" ""))]
10004                 UNSPEC_TOCPTR))
10005    (match_dup 1)]
10006   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10007   "bcl 20,31,$+8\;.long %0-$"
10008   [(set_attr "type" "branch")
10009    (set_attr "length" "8")])
10011 (define_insn "load_toc_v4_PIC_1b_476"
10012   [(set (reg:SI LR_REGNO)
10013         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10014                     (label_ref (match_operand 1 "" ""))]
10015                 UNSPEC_TOCPTR))
10016    (match_dup 1)]
10017   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10018   "*
10020   char name[32];
10021   static char templ[32];
10023   get_ppc476_thunk_name (name);
10024   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10025   return templ;
10027   [(set_attr "type" "branch")
10028    (set_attr "length" "16")])
10030 (define_insn "load_toc_v4_PIC_2"
10031   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10032         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10033                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10034                              (match_operand:SI 3 "immediate_operand" "s")))))]
10035   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10036   "lwz %0,%2-%3(%1)"
10037   [(set_attr "type" "load")])
10039 (define_insn "load_toc_v4_PIC_3b"
10040   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10041         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10042                  (high:SI
10043                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10044                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10045   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10046   "addis %0,%1,%2-%3@ha")
10048 (define_insn "load_toc_v4_PIC_3c"
10049   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10050         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10051                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10052                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10053   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10054   "addi %0,%1,%2-%3@l")
10056 ;; If the TOC is shared over a translation unit, as happens with all
10057 ;; the kinds of PIC that we support, we need to restore the TOC
10058 ;; pointer only when jumping over units of translation.
10059 ;; On Darwin, we need to reload the picbase.
10061 (define_expand "builtin_setjmp_receiver"
10062   [(use (label_ref (match_operand 0 "" "")))]
10063   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10064    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10065    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10066   "
10068 #if TARGET_MACHO
10069   if (DEFAULT_ABI == ABI_DARWIN)
10070     {
10071       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10072       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10073       rtx tmplabrtx;
10074       char tmplab[20];
10076       crtl->uses_pic_offset_table = 1;
10077       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10078                                   CODE_LABEL_NUMBER (operands[0]));
10079       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10081       emit_insn (gen_load_macho_picbase (tmplabrtx));
10082       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10083       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10084     }
10085   else
10086 #endif
10087     rs6000_emit_load_toc_table (FALSE);
10088   DONE;
10091 ;; Largetoc support
10092 (define_insn "*largetoc_high"
10093   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10094         (high:DI
10095           (unspec [(match_operand:DI 1 "" "")
10096                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10097                   UNSPEC_TOCREL)))]
10098    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10099    "addis %0,%2,%1@toc@ha")
10101 (define_insn "*largetoc_high_aix<mode>"
10102   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10103         (high:P
10104           (unspec [(match_operand:P 1 "" "")
10105                    (match_operand:P 2 "gpc_reg_operand" "b")]
10106                   UNSPEC_TOCREL)))]
10107    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10108    "addis %0,%1@u(%2)")
10110 (define_insn "*largetoc_high_plus"
10111   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10112         (high:DI
10113           (plus:DI
10114             (unspec [(match_operand:DI 1 "" "")
10115                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10116                     UNSPEC_TOCREL)
10117             (match_operand:DI 3 "add_cint_operand" "n"))))]
10118    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10119    "addis %0,%2,%1+%3@toc@ha")
10121 (define_insn "*largetoc_high_plus_aix<mode>"
10122   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10123         (high:P
10124           (plus:P
10125             (unspec [(match_operand:P 1 "" "")
10126                      (match_operand:P 2 "gpc_reg_operand" "b")]
10127                     UNSPEC_TOCREL)
10128             (match_operand:P 3 "add_cint_operand" "n"))))]
10129    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10130    "addis %0,%1+%3@u(%2)")
10132 (define_insn "*largetoc_low"
10133   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10134         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10135                    (match_operand:DI 2 "" "")))]
10136    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10137    "addi %0,%1,%2@l")
10139 (define_insn "*largetoc_low_aix<mode>"
10140   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10141         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10142                    (match_operand:P 2 "" "")))]
10143    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10144    "la %0,%2@l(%1)")
10146 (define_insn_and_split "*tocref<mode>"
10147   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10148         (match_operand:P 1 "small_toc_ref" "R"))]
10149    "TARGET_TOC"
10150    "la %0,%a1"
10151    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10152   [(set (match_dup 0) (high:P (match_dup 1)))
10153    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10155 ;; Elf specific ways of loading addresses for non-PIC code.
10156 ;; The output of this could be r0, but we make a very strong
10157 ;; preference for a base register because it will usually
10158 ;; be needed there.
10159 (define_insn "elf_high"
10160   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10161         (high:SI (match_operand 1 "" "")))]
10162   "TARGET_ELF && ! TARGET_64BIT"
10163   "lis %0,%1@ha")
10165 (define_insn "elf_low"
10166   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10167         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10168                    (match_operand 2 "" "")))]
10169    "TARGET_ELF && ! TARGET_64BIT"
10170    "la %0,%2@l(%1)")
10172 ;; Call and call_value insns
10173 (define_expand "call"
10174   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10175                     (match_operand 1 "" ""))
10176               (use (match_operand 2 "" ""))
10177               (clobber (reg:SI LR_REGNO))])]
10178   ""
10179   "
10181 #if TARGET_MACHO
10182   if (MACHOPIC_INDIRECT)
10183     operands[0] = machopic_indirect_call_target (operands[0]);
10184 #endif
10186   gcc_assert (GET_CODE (operands[0]) == MEM);
10187   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10189   operands[0] = XEXP (operands[0], 0);
10191   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10192     {
10193       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10194       DONE;
10195     }
10197   if (GET_CODE (operands[0]) != SYMBOL_REF
10198       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10199     {
10200       if (INTVAL (operands[2]) & CALL_LONG)
10201         operands[0] = rs6000_longcall_ref (operands[0]);
10203       switch (DEFAULT_ABI)
10204         {
10205         case ABI_V4:
10206         case ABI_DARWIN:
10207           operands[0] = force_reg (Pmode, operands[0]);
10208           break;
10210         default:
10211           gcc_unreachable ();
10212         }
10213     }
10216 (define_expand "call_value"
10217   [(parallel [(set (match_operand 0 "" "")
10218                    (call (mem:SI (match_operand 1 "address_operand" ""))
10219                          (match_operand 2 "" "")))
10220               (use (match_operand 3 "" ""))
10221               (clobber (reg:SI LR_REGNO))])]
10222   ""
10223   "
10225 #if TARGET_MACHO
10226   if (MACHOPIC_INDIRECT)
10227     operands[1] = machopic_indirect_call_target (operands[1]);
10228 #endif
10230   gcc_assert (GET_CODE (operands[1]) == MEM);
10231   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10233   operands[1] = XEXP (operands[1], 0);
10235   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10236     {
10237       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10238       DONE;
10239     }
10241   if (GET_CODE (operands[1]) != SYMBOL_REF
10242       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10243     {
10244       if (INTVAL (operands[3]) & CALL_LONG)
10245         operands[1] = rs6000_longcall_ref (operands[1]);
10247       switch (DEFAULT_ABI)
10248         {
10249         case ABI_V4:
10250         case ABI_DARWIN:
10251           operands[1] = force_reg (Pmode, operands[1]);
10252           break;
10254         default:
10255           gcc_unreachable ();
10256         }
10257     }
10260 ;; Call to function in current module.  No TOC pointer reload needed.
10261 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10262 ;; either the function was not prototyped, or it was prototyped as a
10263 ;; variable argument function.  It is > 0 if FP registers were passed
10264 ;; and < 0 if they were not.
10266 (define_insn "*call_local32"
10267   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10268          (match_operand 1 "" "g,g"))
10269    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10270    (clobber (reg:SI LR_REGNO))]
10271   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10272   "*
10274   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10275     output_asm_insn (\"crxor 6,6,6\", operands);
10277   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10278     output_asm_insn (\"creqv 6,6,6\", operands);
10280   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10282   [(set_attr "type" "branch")
10283    (set_attr "length" "4,8")])
10285 (define_insn "*call_local64"
10286   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10287          (match_operand 1 "" "g,g"))
10288    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10289    (clobber (reg:SI LR_REGNO))]
10290   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10291   "*
10293   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10294     output_asm_insn (\"crxor 6,6,6\", operands);
10296   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10297     output_asm_insn (\"creqv 6,6,6\", operands);
10299   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10301   [(set_attr "type" "branch")
10302    (set_attr "length" "4,8")])
10304 (define_insn "*call_value_local32"
10305   [(set (match_operand 0 "" "")
10306         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10307               (match_operand 2 "" "g,g")))
10308    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10309    (clobber (reg:SI LR_REGNO))]
10310   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10311   "*
10313   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10314     output_asm_insn (\"crxor 6,6,6\", operands);
10316   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10317     output_asm_insn (\"creqv 6,6,6\", operands);
10319   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10321   [(set_attr "type" "branch")
10322    (set_attr "length" "4,8")])
10325 (define_insn "*call_value_local64"
10326   [(set (match_operand 0 "" "")
10327         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10328               (match_operand 2 "" "g,g")))
10329    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10330    (clobber (reg:SI LR_REGNO))]
10331   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10332   "*
10334   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10335     output_asm_insn (\"crxor 6,6,6\", operands);
10337   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10338     output_asm_insn (\"creqv 6,6,6\", operands);
10340   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10342   [(set_attr "type" "branch")
10343    (set_attr "length" "4,8")])
10346 ;; A function pointer under System V is just a normal pointer
10347 ;; operands[0] is the function pointer
10348 ;; operands[1] is the stack size to clean up
10349 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10350 ;; which indicates how to set cr1
10352 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10353   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10354          (match_operand 1 "" "g,g,g,g"))
10355    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10356    (clobber (reg:SI LR_REGNO))]
10357   "DEFAULT_ABI == ABI_V4
10358    || DEFAULT_ABI == ABI_DARWIN"
10360   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10361     output_asm_insn ("crxor 6,6,6", operands);
10363   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10364     output_asm_insn ("creqv 6,6,6", operands);
10366   return "b%T0l";
10368   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10369    (set_attr "length" "4,4,8,8")])
10371 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10372   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10373          (match_operand 1 "" "g,g"))
10374    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10375    (clobber (reg:SI LR_REGNO))]
10376   "(DEFAULT_ABI == ABI_DARWIN
10377    || (DEFAULT_ABI == ABI_V4
10378        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10380   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10381     output_asm_insn ("crxor 6,6,6", operands);
10383   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10384     output_asm_insn ("creqv 6,6,6", operands);
10386 #if TARGET_MACHO
10387   return output_call(insn, operands, 0, 2);
10388 #else
10389   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10390     {
10391       gcc_assert (!TARGET_SECURE_PLT);
10392       return "bl %z0@plt";
10393     }
10394   else
10395     return "bl %z0";
10396 #endif
10398   "DEFAULT_ABI == ABI_V4
10399    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10400    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10401   [(parallel [(call (mem:SI (match_dup 0))
10402                     (match_dup 1))
10403               (use (match_dup 2))
10404               (use (match_dup 3))
10405               (clobber (reg:SI LR_REGNO))])]
10407   operands[3] = pic_offset_table_rtx;
10409   [(set_attr "type" "branch,branch")
10410    (set_attr "length" "4,8")])
10412 (define_insn "*call_nonlocal_sysv_secure<mode>"
10413   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10414          (match_operand 1 "" "g,g"))
10415    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10416    (use (match_operand:SI 3 "register_operand" "r,r"))
10417    (clobber (reg:SI LR_REGNO))]
10418   "(DEFAULT_ABI == ABI_V4
10419     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10420     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10422   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10423     output_asm_insn ("crxor 6,6,6", operands);
10425   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10426     output_asm_insn ("creqv 6,6,6", operands);
10428   if (flag_pic == 2)
10429     /* The magic 32768 offset here and in the other sysv call insns
10430        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10431        See sysv4.h:toc_section.  */
10432     return "bl %z0+32768@plt";
10433   else
10434     return "bl %z0@plt";
10436   [(set_attr "type" "branch,branch")
10437    (set_attr "length" "4,8")])
10439 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10440   [(set (match_operand 0 "" "")
10441         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10442               (match_operand 2 "" "g,g,g,g")))
10443    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10444    (clobber (reg:SI LR_REGNO))]
10445   "DEFAULT_ABI == ABI_V4
10446    || DEFAULT_ABI == ABI_DARWIN"
10448   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10449     output_asm_insn ("crxor 6,6,6", operands);
10451   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10452     output_asm_insn ("creqv 6,6,6", operands);
10454   return "b%T1l";
10456   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10457    (set_attr "length" "4,4,8,8")])
10459 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10460   [(set (match_operand 0 "" "")
10461         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10462               (match_operand 2 "" "g,g")))
10463    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10464    (clobber (reg:SI LR_REGNO))]
10465   "(DEFAULT_ABI == ABI_DARWIN
10466    || (DEFAULT_ABI == ABI_V4
10467        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10469   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10470     output_asm_insn ("crxor 6,6,6", operands);
10472   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10473     output_asm_insn ("creqv 6,6,6", operands);
10475 #if TARGET_MACHO
10476   return output_call(insn, operands, 1, 3);
10477 #else
10478   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10479     {
10480       gcc_assert (!TARGET_SECURE_PLT);
10481       return "bl %z1@plt";
10482     }
10483   else
10484     return "bl %z1";
10485 #endif
10487   "DEFAULT_ABI == ABI_V4
10488    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10489    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10490   [(parallel [(set (match_dup 0)
10491                    (call (mem:SI (match_dup 1))
10492                          (match_dup 2)))
10493               (use (match_dup 3))
10494               (use (match_dup 4))
10495               (clobber (reg:SI LR_REGNO))])]
10497   operands[4] = pic_offset_table_rtx;
10499   [(set_attr "type" "branch,branch")
10500    (set_attr "length" "4,8")])
10502 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10503   [(set (match_operand 0 "" "")
10504         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10505               (match_operand 2 "" "g,g")))
10506    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10507    (use (match_operand:SI 4 "register_operand" "r,r"))
10508    (clobber (reg:SI LR_REGNO))]
10509   "(DEFAULT_ABI == ABI_V4
10510     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10511     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10513   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10514     output_asm_insn ("crxor 6,6,6", operands);
10516   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10517     output_asm_insn ("creqv 6,6,6", operands);
10519   if (flag_pic == 2)
10520     return "bl %z1+32768@plt";
10521   else
10522     return "bl %z1@plt";
10524   [(set_attr "type" "branch,branch")
10525    (set_attr "length" "4,8")])
10528 ;; Call to AIX abi function in the same module.
10530 (define_insn "*call_local_aix<mode>"
10531   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10532          (match_operand 1 "" "g"))
10533    (clobber (reg:P LR_REGNO))]
10534   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10535   "bl %z0"
10536   [(set_attr "type" "branch")
10537    (set_attr "length" "4")])
10539 (define_insn "*call_value_local_aix<mode>"
10540   [(set (match_operand 0 "" "")
10541         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10542               (match_operand 2 "" "g")))
10543    (clobber (reg:P LR_REGNO))]
10544   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10545   "bl %z1"
10546   [(set_attr "type" "branch")
10547    (set_attr "length" "4")])
10549 ;; Call to AIX abi function which may be in another module.
10550 ;; Restore the TOC pointer (r2) after the call.
10552 (define_insn "*call_nonlocal_aix<mode>"
10553   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10554          (match_operand 1 "" "g"))
10555    (clobber (reg:P LR_REGNO))]
10556   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10557   "bl %z0\;nop"
10558   [(set_attr "type" "branch")
10559    (set_attr "length" "8")])
10561 (define_insn "*call_value_nonlocal_aix<mode>"
10562   [(set (match_operand 0 "" "")
10563         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10564               (match_operand 2 "" "g")))
10565    (clobber (reg:P LR_REGNO))]
10566   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10567   "bl %z1\;nop"
10568   [(set_attr "type" "branch")
10569    (set_attr "length" "8")])
10571 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10572 ;; Operand0 is the addresss of the function to call
10573 ;; Operand2 is the location in the function descriptor to load r2 from
10574 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10576 (define_insn "*call_indirect_aix<mode>"
10577   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10578          (match_operand 1 "" "g,g"))
10579    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10580    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10581    (clobber (reg:P LR_REGNO))]
10582   "DEFAULT_ABI == ABI_AIX"
10583   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10584   [(set_attr "type" "jmpreg")
10585    (set_attr "length" "12")])
10587 (define_insn "*call_value_indirect_aix<mode>"
10588   [(set (match_operand 0 "" "")
10589         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10590               (match_operand 2 "" "g,g")))
10591    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10592    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10593    (clobber (reg:P LR_REGNO))]
10594   "DEFAULT_ABI == ABI_AIX"
10595   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10596   [(set_attr "type" "jmpreg")
10597    (set_attr "length" "12")])
10599 ;; Call to indirect functions with the ELFv2 ABI.
10600 ;; Operand0 is the addresss of the function to call
10601 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10603 (define_insn "*call_indirect_elfv2<mode>"
10604   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10605          (match_operand 1 "" "g,g"))
10606    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10607    (clobber (reg:P LR_REGNO))]
10608   "DEFAULT_ABI == ABI_ELFv2"
10609   "b%T0l\;<ptrload> 2,%2(1)"
10610   [(set_attr "type" "jmpreg")
10611    (set_attr "length" "8")])
10613 (define_insn "*call_value_indirect_elfv2<mode>"
10614   [(set (match_operand 0 "" "")
10615         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10616               (match_operand 2 "" "g,g")))
10617    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10618    (clobber (reg:P LR_REGNO))]
10619   "DEFAULT_ABI == ABI_ELFv2"
10620   "b%T1l\;<ptrload> 2,%3(1)"
10621   [(set_attr "type" "jmpreg")
10622    (set_attr "length" "8")])
10625 ;; Call subroutine returning any type.
10626 (define_expand "untyped_call"
10627   [(parallel [(call (match_operand 0 "" "")
10628                     (const_int 0))
10629               (match_operand 1 "" "")
10630               (match_operand 2 "" "")])]
10631   ""
10632   "
10634   int i;
10636   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10638   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10639     {
10640       rtx set = XVECEXP (operands[2], 0, i);
10641       emit_move_insn (SET_DEST (set), SET_SRC (set));
10642     }
10644   /* The optimizer does not know that the call sets the function value
10645      registers we stored in the result block.  We avoid problems by
10646      claiming that all hard registers are used and clobbered at this
10647      point.  */
10648   emit_insn (gen_blockage ());
10650   DONE;
10653 ;; sibling call patterns
10654 (define_expand "sibcall"
10655   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10656                     (match_operand 1 "" ""))
10657               (use (match_operand 2 "" ""))
10658               (simple_return)])]
10659   ""
10660   "
10662 #if TARGET_MACHO
10663   if (MACHOPIC_INDIRECT)
10664     operands[0] = machopic_indirect_call_target (operands[0]);
10665 #endif
10667   gcc_assert (GET_CODE (operands[0]) == MEM);
10668   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10670   operands[0] = XEXP (operands[0], 0);
10672   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10673     {
10674       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10675       DONE;
10676     }
10679 (define_expand "sibcall_value"
10680   [(parallel [(set (match_operand 0 "register_operand" "")
10681                 (call (mem:SI (match_operand 1 "address_operand" ""))
10682                       (match_operand 2 "" "")))
10683               (use (match_operand 3 "" ""))
10684               (simple_return)])]
10685   ""
10686   "
10688 #if TARGET_MACHO
10689   if (MACHOPIC_INDIRECT)
10690     operands[1] = machopic_indirect_call_target (operands[1]);
10691 #endif
10693   gcc_assert (GET_CODE (operands[1]) == MEM);
10694   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10696   operands[1] = XEXP (operands[1], 0);
10698   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10699     {
10700       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10701       DONE;
10702     }
10705 (define_insn "*sibcall_local32"
10706   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10707          (match_operand 1 "" "g,g"))
10708    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10709    (simple_return)]
10710   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10711   "*
10713   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10714     output_asm_insn (\"crxor 6,6,6\", operands);
10716   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10717     output_asm_insn (\"creqv 6,6,6\", operands);
10719   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10721   [(set_attr "type" "branch")
10722    (set_attr "length" "4,8")])
10724 (define_insn "*sibcall_local64"
10725   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10726          (match_operand 1 "" "g,g"))
10727    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10728    (simple_return)]
10729   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10730   "*
10732   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10733     output_asm_insn (\"crxor 6,6,6\", operands);
10735   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10736     output_asm_insn (\"creqv 6,6,6\", operands);
10738   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10740   [(set_attr "type" "branch")
10741    (set_attr "length" "4,8")])
10743 (define_insn "*sibcall_value_local32"
10744   [(set (match_operand 0 "" "")
10745         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10746               (match_operand 2 "" "g,g")))
10747    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10748    (simple_return)]
10749   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10750   "*
10752   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10753     output_asm_insn (\"crxor 6,6,6\", operands);
10755   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10756     output_asm_insn (\"creqv 6,6,6\", operands);
10758   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10760   [(set_attr "type" "branch")
10761    (set_attr "length" "4,8")])
10763 (define_insn "*sibcall_value_local64"
10764   [(set (match_operand 0 "" "")
10765         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10766               (match_operand 2 "" "g,g")))
10767    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10768    (simple_return)]
10769   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10770   "*
10772   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10773     output_asm_insn (\"crxor 6,6,6\", operands);
10775   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10776     output_asm_insn (\"creqv 6,6,6\", operands);
10778   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10780   [(set_attr "type" "branch")
10781    (set_attr "length" "4,8")])
10783 (define_insn "*sibcall_nonlocal_sysv<mode>"
10784   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10785          (match_operand 1 "" ""))
10786    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10787    (simple_return)]
10788   "(DEFAULT_ABI == ABI_DARWIN
10789     || DEFAULT_ABI == ABI_V4)
10790    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10791   "*
10793   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10794     output_asm_insn (\"crxor 6,6,6\", operands);
10796   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10797     output_asm_insn (\"creqv 6,6,6\", operands);
10799   if (which_alternative >= 2)
10800     return \"b%T0\";
10801   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10802     {
10803       gcc_assert (!TARGET_SECURE_PLT);
10804       return \"b %z0@plt\";
10805     }
10806   else
10807     return \"b %z0\";
10809   [(set_attr "type" "branch")
10810    (set_attr "length" "4,8,4,8")])
10812 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10813   [(set (match_operand 0 "" "")
10814         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10815               (match_operand 2 "" "")))
10816    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10817    (simple_return)]
10818   "(DEFAULT_ABI == ABI_DARWIN
10819     || DEFAULT_ABI == ABI_V4)
10820    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10821   "*
10823   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10824     output_asm_insn (\"crxor 6,6,6\", operands);
10826   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10827     output_asm_insn (\"creqv 6,6,6\", operands);
10829   if (which_alternative >= 2)
10830     return \"b%T1\";
10831   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10832     {
10833       gcc_assert (!TARGET_SECURE_PLT);
10834       return \"b %z1@plt\";
10835     }
10836   else
10837     return \"b %z1\";
10839   [(set_attr "type" "branch")
10840    (set_attr "length" "4,8,4,8")])
10842 ;; AIX ABI sibling call patterns.
10844 (define_insn "*sibcall_aix<mode>"
10845   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10846          (match_operand 1 "" "g,g"))
10847    (simple_return)]
10848   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10849   "@
10850    b %z0
10851    b%T0"
10852   [(set_attr "type" "branch")
10853    (set_attr "length" "4")])
10855 (define_insn "*sibcall_value_aix<mode>"
10856   [(set (match_operand 0 "" "")
10857         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10858               (match_operand 2 "" "g,g")))
10859    (simple_return)]
10860   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10861   "@
10862    b %z1
10863    b%T1"
10864   [(set_attr "type" "branch")
10865    (set_attr "length" "4")])
10867 (define_expand "sibcall_epilogue"
10868   [(use (const_int 0))]
10869   ""
10871   if (!TARGET_SCHED_PROLOG)
10872     emit_insn (gen_blockage ());
10873   rs6000_emit_epilogue (TRUE);
10874   DONE;
10877 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10878 ;; all of memory.  This blocks insns from being moved across this point.
10880 (define_insn "blockage"
10881   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10882   ""
10883   "")
10885 (define_expand "probe_stack_address"
10886   [(use (match_operand 0 "address_operand"))]
10887   ""
10889   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10890   MEM_VOLATILE_P (operands[0]) = 1;
10892   if (TARGET_64BIT)
10893     emit_insn (gen_probe_stack_di (operands[0]));
10894   else
10895     emit_insn (gen_probe_stack_si (operands[0]));
10896   DONE;
10899 (define_insn "probe_stack_<mode>"
10900   [(set (match_operand:P 0 "memory_operand" "=m")
10901         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10902   ""
10904   operands[1] = gen_rtx_REG (Pmode, 0);
10905   return "st<wd>%U0%X0 %1,%0";
10907   [(set_attr "type" "store")
10908    (set (attr "update")
10909         (if_then_else (match_operand 0 "update_address_mem")
10910                       (const_string "yes")
10911                       (const_string "no")))
10912    (set (attr "indexed")
10913         (if_then_else (match_operand 0 "indexed_address_mem")
10914                       (const_string "yes")
10915                       (const_string "no")))
10916    (set_attr "length" "4")])
10918 (define_insn "probe_stack_range<P:mode>"
10919   [(set (match_operand:P 0 "register_operand" "=r")
10920         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10921                             (match_operand:P 2 "register_operand" "r")]
10922                            UNSPECV_PROBE_STACK_RANGE))]
10923   ""
10924   "* return output_probe_stack_range (operands[0], operands[2]);"
10925   [(set_attr "type" "three")])
10927 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10928 ;; signed & unsigned, and one type of branch.
10930 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10931 ;; insns, and branches.
10933 (define_expand "cbranch<mode>4"
10934   [(use (match_operator 0 "rs6000_cbranch_operator"
10935          [(match_operand:GPR 1 "gpc_reg_operand" "")
10936           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10937    (use (match_operand 3 ""))]
10938   ""
10939   "
10941   /* Take care of the possibility that operands[2] might be negative but
10942      this might be a logical operation.  That insn doesn't exist.  */
10943   if (GET_CODE (operands[2]) == CONST_INT
10944       && INTVAL (operands[2]) < 0)
10945     {
10946       operands[2] = force_reg (<MODE>mode, operands[2]);
10947       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10948                                     GET_MODE (operands[0]),
10949                                     operands[1], operands[2]);
10950    }
10952   rs6000_emit_cbranch (<MODE>mode, operands);
10953   DONE;
10956 (define_expand "cbranch<mode>4"
10957   [(use (match_operator 0 "rs6000_cbranch_operator"
10958          [(match_operand:FP 1 "gpc_reg_operand" "")
10959           (match_operand:FP 2 "gpc_reg_operand" "")]))
10960    (use (match_operand 3 ""))]
10961   ""
10962   "
10964   rs6000_emit_cbranch (<MODE>mode, operands);
10965   DONE;
10968 (define_expand "cstore<mode>4_signed"
10969   [(use (match_operator 1 "signed_comparison_operator"
10970          [(match_operand:P 2 "gpc_reg_operand")
10971           (match_operand:P 3 "gpc_reg_operand")]))
10972    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10973   ""
10975   enum rtx_code cond_code = GET_CODE (operands[1]);
10977   rtx op0 = operands[0];
10978   rtx op1 = operands[2];
10979   rtx op2 = operands[3];
10981   if (cond_code == GE || cond_code == LT)
10982     {
10983       cond_code = swap_condition (cond_code);
10984       std::swap (op1, op2);
10985     }
10987   rtx tmp1 = gen_reg_rtx (<MODE>mode);
10988   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10989   rtx tmp3 = gen_reg_rtx (<MODE>mode);
10991   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10992   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10993   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10995   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10997   if (cond_code == LE)
10998     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10999   else
11000     {
11001       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11002       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11003       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11004     }
11006   DONE;
11009 (define_expand "cstore<mode>4_unsigned"
11010   [(use (match_operator 1 "unsigned_comparison_operator"
11011          [(match_operand:P 2 "gpc_reg_operand")
11012           (match_operand:P 3 "reg_or_short_operand")]))
11013    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11014   ""
11016   enum rtx_code cond_code = GET_CODE (operands[1]);
11018   rtx op0 = operands[0];
11019   rtx op1 = operands[2];
11020   rtx op2 = operands[3];
11022   if (cond_code == GEU || cond_code == LTU)
11023     {
11024       cond_code = swap_condition (cond_code);
11025       std::swap (op1, op2);
11026     }
11028   if (!gpc_reg_operand (op1, <MODE>mode))
11029     op1 = force_reg (<MODE>mode, op1);
11030   if (!reg_or_short_operand (op2, <MODE>mode))
11031     op2 = force_reg (<MODE>mode, op2);
11033   rtx tmp = gen_reg_rtx (<MODE>mode);
11034   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11036   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11037   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11039   if (cond_code == LEU)
11040     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11041   else
11042     emit_insn (gen_neg<mode>2 (op0, tmp2));
11044   DONE;
11047 (define_expand "cstore_si_as_di"
11048   [(use (match_operator 1 "unsigned_comparison_operator"
11049          [(match_operand:SI 2 "gpc_reg_operand")
11050           (match_operand:SI 3 "reg_or_short_operand")]))
11051    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11052   ""
11054   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11055   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11057   operands[2] = force_reg (SImode, operands[2]);
11058   operands[3] = force_reg (SImode, operands[3]);
11059   rtx op1 = gen_reg_rtx (DImode);
11060   rtx op2 = gen_reg_rtx (DImode);
11061   convert_move (op1, operands[2], uns_flag);
11062   convert_move (op2, operands[3], uns_flag);
11064   if (cond_code == GT || cond_code == LE)
11065     {
11066       cond_code = swap_condition (cond_code);
11067       std::swap (op1, op2);
11068     }
11070   rtx tmp = gen_reg_rtx (DImode);
11071   rtx tmp2 = gen_reg_rtx (DImode);
11072   emit_insn (gen_subdi3 (tmp, op1, op2));
11073   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11075   rtx tmp3;
11076   switch (cond_code)
11077     {
11078     default:
11079       gcc_unreachable ();
11080     case LT:
11081       tmp3 = tmp2;
11082       break;
11083     case GE:
11084       tmp3 = gen_reg_rtx (DImode);
11085       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11086       break;
11087     }
11089   convert_move (operands[0], tmp3, 1);
11091   DONE;
11094 (define_expand "cstore<mode>4_signed_imm"
11095   [(use (match_operator 1 "signed_comparison_operator"
11096          [(match_operand:GPR 2 "gpc_reg_operand")
11097           (match_operand:GPR 3 "immediate_operand")]))
11098    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11099   ""
11101   bool invert = false;
11103   enum rtx_code cond_code = GET_CODE (operands[1]);
11105   rtx op0 = operands[0];
11106   rtx op1 = operands[2];
11107   HOST_WIDE_INT val = INTVAL (operands[3]);
11109   if (cond_code == GE || cond_code == GT)
11110     {
11111       cond_code = reverse_condition (cond_code);
11112       invert = true;
11113     }
11115   if (cond_code == LE)
11116     val++;
11118   rtx tmp = gen_reg_rtx (<MODE>mode);
11119   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11120   rtx x = gen_reg_rtx (<MODE>mode);
11121   if (val < 0)
11122     emit_insn (gen_and<mode>3 (x, op1, tmp));
11123   else
11124     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11126   if (invert)
11127     {
11128       rtx tmp = gen_reg_rtx (<MODE>mode);
11129       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11130       x = tmp;
11131     }
11133   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11134   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11136   DONE;
11139 (define_expand "cstore<mode>4_unsigned_imm"
11140   [(use (match_operator 1 "unsigned_comparison_operator"
11141          [(match_operand:GPR 2 "gpc_reg_operand")
11142           (match_operand:GPR 3 "immediate_operand")]))
11143    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11144   ""
11146   bool invert = false;
11148   enum rtx_code cond_code = GET_CODE (operands[1]);
11150   rtx op0 = operands[0];
11151   rtx op1 = operands[2];
11152   HOST_WIDE_INT val = INTVAL (operands[3]);
11154   if (cond_code == GEU || cond_code == GTU)
11155     {
11156       cond_code = reverse_condition (cond_code);
11157       invert = true;
11158     }
11160   if (cond_code == LEU)
11161     val++;
11163   rtx tmp = gen_reg_rtx (<MODE>mode);
11164   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11165   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11166   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11167   rtx x = gen_reg_rtx (<MODE>mode);
11168   if (val < 0)
11169     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11170   else
11171     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11173   if (invert)
11174     {
11175       rtx tmp = gen_reg_rtx (<MODE>mode);
11176       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11177       x = tmp;
11178     }
11180   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11181   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11183   DONE;
11186 (define_expand "cstore<mode>4"
11187   [(use (match_operator 1 "rs6000_cbranch_operator"
11188          [(match_operand:GPR 2 "gpc_reg_operand")
11189           (match_operand:GPR 3 "reg_or_short_operand")]))
11190    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11191   ""
11193   /* Use ISEL if the user asked for it.  */
11194   if (TARGET_ISEL)
11195     rs6000_emit_sISEL (<MODE>mode, operands);
11197   /* Expanding EQ and NE directly to some machine instructions does not help
11198      but does hurt combine.  So don't.  */
11199   else if (GET_CODE (operands[1]) == EQ)
11200     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11201   else if (<MODE>mode == Pmode
11202            && GET_CODE (operands[1]) == NE)
11203     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11204   else if (GET_CODE (operands[1]) == NE)
11205     {
11206       rtx tmp = gen_reg_rtx (<MODE>mode);
11207       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11208       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11209     }
11211   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11212      etc. combinations magically work out just right.  */
11213   else if (<MODE>mode == Pmode
11214            && unsigned_comparison_operator (operands[1], VOIDmode))
11215     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11216                                            operands[2], operands[3]));
11218   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11219   else if (<MODE>mode == SImode && Pmode == DImode)
11220     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11221                                     operands[2], operands[3]));
11223   /* For signed comparisons against a constant, we can do some simple
11224      bit-twiddling.  */
11225   else if (signed_comparison_operator (operands[1], VOIDmode)
11226            && CONST_INT_P (operands[3]))
11227     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11228                                              operands[2], operands[3]));
11230   /* And similarly for unsigned comparisons.  */
11231   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11232            && CONST_INT_P (operands[3]))
11233     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11234                                                operands[2], operands[3]));
11236   /* We also do not want to use mfcr for signed comparisons.  */
11237   else if (<MODE>mode == Pmode
11238            && signed_comparison_operator (operands[1], VOIDmode))
11239     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11240                                          operands[2], operands[3]));
11242   /* Everything else, use the mfcr brute force.  */
11243   else
11244     rs6000_emit_sCOND (<MODE>mode, operands);
11246   DONE;
11249 (define_expand "cstore<mode>4"
11250   [(use (match_operator 1 "rs6000_cbranch_operator"
11251          [(match_operand:FP 2 "gpc_reg_operand")
11252           (match_operand:FP 3 "gpc_reg_operand")]))
11253    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11254   ""
11256   rs6000_emit_sCOND (<MODE>mode, operands);
11257   DONE;
11261 (define_expand "stack_protect_set"
11262   [(match_operand 0 "memory_operand" "")
11263    (match_operand 1 "memory_operand" "")]
11264   ""
11266 #ifdef TARGET_THREAD_SSP_OFFSET
11267   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11268   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11269   operands[1] = gen_rtx_MEM (Pmode, addr);
11270 #endif
11271   if (TARGET_64BIT)
11272     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11273   else
11274     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11275   DONE;
11278 (define_insn "stack_protect_setsi"
11279   [(set (match_operand:SI 0 "memory_operand" "=m")
11280         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11281    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11282   "TARGET_32BIT"
11283   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11284   [(set_attr "type" "three")
11285    (set_attr "length" "12")])
11287 (define_insn "stack_protect_setdi"
11288   [(set (match_operand:DI 0 "memory_operand" "=Y")
11289         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11290    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11291   "TARGET_64BIT"
11292   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11293   [(set_attr "type" "three")
11294    (set_attr "length" "12")])
11296 (define_expand "stack_protect_test"
11297   [(match_operand 0 "memory_operand" "")
11298    (match_operand 1 "memory_operand" "")
11299    (match_operand 2 "" "")]
11300   ""
11302   rtx test, op0, op1;
11303 #ifdef TARGET_THREAD_SSP_OFFSET
11304   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11305   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11306   operands[1] = gen_rtx_MEM (Pmode, addr);
11307 #endif
11308   op0 = operands[0];
11309   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11310   test = gen_rtx_EQ (VOIDmode, op0, op1);
11311   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11312   DONE;
11315 (define_insn "stack_protect_testsi"
11316   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11317         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11318                       (match_operand:SI 2 "memory_operand" "m,m")]
11319                      UNSPEC_SP_TEST))
11320    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11321    (clobber (match_scratch:SI 3 "=&r,&r"))]
11322   "TARGET_32BIT"
11323   "@
11324    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11325    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11326   [(set_attr "length" "16,20")])
11328 (define_insn "stack_protect_testdi"
11329   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11330         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11331                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11332                      UNSPEC_SP_TEST))
11333    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11334    (clobber (match_scratch:DI 3 "=&r,&r"))]
11335   "TARGET_64BIT"
11336   "@
11337    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11338    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11339   [(set_attr "length" "16,20")])
11342 ;; Here are the actual compare insns.
11343 (define_insn "*cmp<mode>_signed"
11344   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11345         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11346                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11347   ""
11348   "cmp<wd>%I2 %0,%1,%2"
11349   [(set_attr "type" "cmp")])
11351 (define_insn "*cmp<mode>_unsigned"
11352   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11353         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11354                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11355   ""
11356   "cmpl<wd>%I2 %0,%1,%2"
11357   [(set_attr "type" "cmp")])
11359 ;; If we are comparing a register for equality with a large constant,
11360 ;; we can do this with an XOR followed by a compare.  But this is profitable
11361 ;; only if the large constant is only used for the comparison (and in this
11362 ;; case we already have a register to reuse as scratch).
11364 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11365 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11367 (define_peephole2
11368   [(set (match_operand:SI 0 "register_operand")
11369         (match_operand:SI 1 "logical_const_operand" ""))
11370    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11371                        [(match_dup 0)
11372                         (match_operand:SI 2 "logical_const_operand" "")]))
11373    (set (match_operand:CC 4 "cc_reg_operand" "")
11374         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11375                     (match_dup 0)))
11376    (set (pc)
11377         (if_then_else (match_operator 6 "equality_operator"
11378                        [(match_dup 4) (const_int 0)])
11379                       (match_operand 7 "" "")
11380                       (match_operand 8 "" "")))]
11381   "peep2_reg_dead_p (3, operands[0])
11382    && peep2_reg_dead_p (4, operands[4])
11383    && REGNO (operands[0]) != REGNO (operands[5])"
11384  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11385   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11386   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11389   /* Get the constant we are comparing against, and see what it looks like
11390      when sign-extended from 16 to 32 bits.  Then see what constant we could
11391      XOR with SEXTC to get the sign-extended value.  */
11392   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11393                                               SImode,
11394                                               operands[1], operands[2]);
11395   HOST_WIDE_INT c = INTVAL (cnst);
11396   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11397   HOST_WIDE_INT xorv = c ^ sextc;
11399   operands[9] = GEN_INT (xorv);
11400   operands[10] = GEN_INT (sextc);
11403 ;; The following two insns don't exist as single insns, but if we provide
11404 ;; them, we can swap an add and compare, which will enable us to overlap more
11405 ;; of the required delay between a compare and branch.  We generate code for
11406 ;; them by splitting.
11408 (define_insn ""
11409   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11410         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11411                     (match_operand:SI 2 "short_cint_operand" "i")))
11412    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11413         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11414   ""
11415   "#"
11416   [(set_attr "length" "8")])
11418 (define_insn ""
11419   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11420         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11421                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11422    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11423         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11424   ""
11425   "#"
11426   [(set_attr "length" "8")])
11428 (define_split
11429   [(set (match_operand:CC 3 "cc_reg_operand" "")
11430         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11431                     (match_operand:SI 2 "short_cint_operand" "")))
11432    (set (match_operand:SI 0 "gpc_reg_operand" "")
11433         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11434   ""
11435   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11436    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11438 (define_split
11439   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11440         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11441                        (match_operand:SI 2 "u_short_cint_operand" "")))
11442    (set (match_operand:SI 0 "gpc_reg_operand" "")
11443         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11444   ""
11445   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11446    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11448 ;; Only need to compare second words if first words equal
11449 (define_insn "*cmp<mode>_internal1"
11450   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11451         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11452                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11453   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11454    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11455   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11456   [(set_attr "type" "fpcompare")
11457    (set_attr "length" "12")])
11459 (define_insn_and_split "*cmp<mode>_internal2"
11460   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11461         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11462                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11463     (clobber (match_scratch:DF 3 "=d"))
11464     (clobber (match_scratch:DF 4 "=d"))
11465     (clobber (match_scratch:DF 5 "=d"))
11466     (clobber (match_scratch:DF 6 "=d"))
11467     (clobber (match_scratch:DF 7 "=d"))
11468     (clobber (match_scratch:DF 8 "=d"))
11469     (clobber (match_scratch:DF 9 "=d"))
11470     (clobber (match_scratch:DF 10 "=d"))
11471     (clobber (match_scratch:GPR 11 "=b"))]
11472   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11473    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11474   "#"
11475   "&& reload_completed"
11476   [(set (match_dup 3) (match_dup 14))
11477    (set (match_dup 4) (match_dup 15))
11478    (set (match_dup 9) (abs:DF (match_dup 5)))
11479    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11480    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11481                            (label_ref (match_dup 12))
11482                            (pc)))
11483    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11484    (set (pc) (label_ref (match_dup 13)))
11485    (match_dup 12)
11486    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11487    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11488    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11489    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11490    (match_dup 13)]
11492   REAL_VALUE_TYPE rv;
11493   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11494   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11496   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11497   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11498   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11499   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11500   operands[12] = gen_label_rtx ();
11501   operands[13] = gen_label_rtx ();
11502   real_inf (&rv);
11503   operands[14] = force_const_mem (DFmode,
11504                                   const_double_from_real_value (rv, DFmode));
11505   operands[15] = force_const_mem (DFmode,
11506                                   const_double_from_real_value (dconst0,
11507                                                                 DFmode));
11508   if (TARGET_TOC)
11509     {
11510       rtx tocref;
11511       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11512       operands[14] = gen_const_mem (DFmode, tocref);
11513       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11514       operands[15] = gen_const_mem (DFmode, tocref);
11515       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11516       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11517     }
11520 ;; Now we have the scc insns.  We can do some combinations because of the
11521 ;; way the machine works.
11523 ;; Note that this is probably faster if we can put an insn between the
11524 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11525 ;; cases the insns below which don't use an intermediate CR field will
11526 ;; be used instead.
11527 (define_insn ""
11528   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11529         (match_operator:SI 1 "scc_comparison_operator"
11530                            [(match_operand 2 "cc_reg_operand" "y")
11531                             (const_int 0)]))]
11532   ""
11533   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11534   [(set (attr "type")
11535      (cond [(match_test "TARGET_MFCRF")
11536                 (const_string "mfcrf")
11537            ]
11538         (const_string "mfcr")))
11539    (set_attr "length" "8")])
11541 ;; Same as above, but get the GT bit.
11542 (define_insn "move_from_CR_gt_bit"
11543   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11544         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11545   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11546   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11547   [(set_attr "type" "mfcr")
11548    (set_attr "length" "8")])
11550 ;; Same as above, but get the OV/ORDERED bit.
11551 (define_insn "move_from_CR_ov_bit"
11552   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11553         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11554                    UNSPEC_MV_CR_OV))]
11555   "TARGET_ISEL"
11556   "mfcr %0\;rlwinm %0,%0,%t1,1"
11557   [(set_attr "type" "mfcr")
11558    (set_attr "length" "8")])
11560 (define_insn ""
11561   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11562         (match_operator:DI 1 "scc_comparison_operator"
11563                            [(match_operand 2 "cc_reg_operand" "y")
11564                             (const_int 0)]))]
11565   "TARGET_POWERPC64"
11566   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11567   [(set (attr "type")
11568      (cond [(match_test "TARGET_MFCRF")
11569                 (const_string "mfcrf")
11570            ]
11571         (const_string "mfcr")))
11572    (set_attr "length" "8")])
11574 (define_insn ""
11575   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11576         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11577                                        [(match_operand 2 "cc_reg_operand" "y,y")
11578                                         (const_int 0)])
11579                     (const_int 0)))
11580    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11581         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11582   "TARGET_32BIT"
11583   "@
11584    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11585    #"
11586   [(set_attr "type" "shift")
11587    (set_attr "dot" "yes")
11588    (set_attr "length" "8,16")])
11590 (define_split
11591   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11592         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11593                                        [(match_operand 2 "cc_reg_operand" "")
11594                                         (const_int 0)])
11595                     (const_int 0)))
11596    (set (match_operand:SI 3 "gpc_reg_operand" "")
11597         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11598   "TARGET_32BIT && reload_completed"
11599   [(set (match_dup 3)
11600         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11601    (set (match_dup 0)
11602         (compare:CC (match_dup 3)
11603                     (const_int 0)))]
11604   "")
11606 (define_insn ""
11607   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11608         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11609                                       [(match_operand 2 "cc_reg_operand" "y")
11610                                        (const_int 0)])
11611                    (match_operand:SI 3 "const_int_operand" "n")))]
11612   ""
11613   "*
11615   int is_bit = ccr_bit (operands[1], 1);
11616   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11617   int count;
11619   if (is_bit >= put_bit)
11620     count = is_bit - put_bit;
11621   else
11622     count = 32 - (put_bit - is_bit);
11624   operands[4] = GEN_INT (count);
11625   operands[5] = GEN_INT (put_bit);
11627   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11629   [(set (attr "type")
11630      (cond [(match_test "TARGET_MFCRF")
11631                 (const_string "mfcrf")
11632            ]
11633         (const_string "mfcr")))
11634    (set_attr "length" "8")])
11636 (define_insn ""
11637   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11638         (compare:CC
11639          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11640                                        [(match_operand 2 "cc_reg_operand" "y,y")
11641                                         (const_int 0)])
11642                     (match_operand:SI 3 "const_int_operand" "n,n"))
11643          (const_int 0)))
11644    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11645         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11646                    (match_dup 3)))]
11647   ""
11648   "*
11650   int is_bit = ccr_bit (operands[1], 1);
11651   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11652   int count;
11654   /* Force split for non-cc0 compare.  */
11655   if (which_alternative == 1)
11656      return \"#\";
11658   if (is_bit >= put_bit)
11659     count = is_bit - put_bit;
11660   else
11661     count = 32 - (put_bit - is_bit);
11663   operands[5] = GEN_INT (count);
11664   operands[6] = GEN_INT (put_bit);
11666   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11668   [(set_attr "type" "shift")
11669    (set_attr "dot" "yes")
11670    (set_attr "length" "8,16")])
11672 (define_split
11673   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11674         (compare:CC
11675          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11676                                        [(match_operand 2 "cc_reg_operand" "")
11677                                         (const_int 0)])
11678                     (match_operand:SI 3 "const_int_operand" ""))
11679          (const_int 0)))
11680    (set (match_operand:SI 4 "gpc_reg_operand" "")
11681         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11682                    (match_dup 3)))]
11683   "reload_completed"
11684   [(set (match_dup 4)
11685         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11686                    (match_dup 3)))
11687    (set (match_dup 0)
11688         (compare:CC (match_dup 4)
11689                     (const_int 0)))]
11690   "")
11693 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11694                               (DI "rKJI")])
11696 (define_insn_and_split "eq<mode>3"
11697   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11698         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11699                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11700    (clobber (match_scratch:GPR 3 "=r"))
11701    (clobber (match_scratch:GPR 4 "=r"))]
11702   ""
11703   "#"
11704   ""
11705   [(set (match_dup 4)
11706         (clz:GPR (match_dup 3)))
11707    (set (match_dup 0)
11708         (lshiftrt:GPR (match_dup 4)
11709                       (match_dup 5)))]
11711   operands[3] = rs6000_emit_eqne (<MODE>mode,
11712                                   operands[1], operands[2], operands[3]);
11714   if (GET_CODE (operands[4]) == SCRATCH)
11715     operands[4] = gen_reg_rtx (<MODE>mode);
11717   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11719   [(set (attr "length")
11720         (if_then_else (match_test "operands[2] == const0_rtx")
11721                       (const_string "8")
11722                       (const_string "12")))])
11724 (define_insn_and_split "ne<mode>3"
11725   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11726         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11727               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11728    (clobber (match_scratch:P 3 "=r"))
11729    (clobber (match_scratch:P 4 "=r"))
11730    (clobber (reg:P CA_REGNO))]
11731   "!TARGET_ISEL"
11732   "#"
11733   ""
11734   [(parallel [(set (match_dup 4)
11735                    (plus:P (match_dup 3)
11736                            (const_int -1)))
11737               (set (reg:P CA_REGNO)
11738                    (ne:P (match_dup 3)
11739                          (const_int 0)))])
11740    (parallel [(set (match_dup 0)
11741                    (plus:P (plus:P (not:P (match_dup 4))
11742                                    (reg:P CA_REGNO))
11743                            (match_dup 3)))
11744               (clobber (reg:P CA_REGNO))])]
11746   operands[3] = rs6000_emit_eqne (<MODE>mode,
11747                                   operands[1], operands[2], operands[3]);
11749   if (GET_CODE (operands[4]) == SCRATCH)
11750     operands[4] = gen_reg_rtx (<MODE>mode);
11752   [(set (attr "length")
11753         (if_then_else (match_test "operands[2] == const0_rtx")
11754                       (const_string "8")
11755                       (const_string "12")))])
11757 (define_insn_and_split "*neg_eq_<mode>"
11758   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11759         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11760                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11761    (clobber (match_scratch:P 3 "=r"))
11762    (clobber (match_scratch:P 4 "=r"))
11763    (clobber (reg:P CA_REGNO))]
11764   ""
11765   "#"
11766   ""
11767   [(parallel [(set (match_dup 4)
11768                    (plus:P (match_dup 3)
11769                            (const_int -1)))
11770               (set (reg:P CA_REGNO)
11771                    (ne:P (match_dup 3)
11772                          (const_int 0)))])
11773    (parallel [(set (match_dup 0)
11774                    (plus:P (reg:P CA_REGNO)
11775                            (const_int -1)))
11776               (clobber (reg:P CA_REGNO))])]
11778   operands[3] = rs6000_emit_eqne (<MODE>mode,
11779                                   operands[1], operands[2], operands[3]);
11781   if (GET_CODE (operands[4]) == SCRATCH)
11782     operands[4] = gen_reg_rtx (<MODE>mode);
11784   [(set (attr "length")
11785         (if_then_else (match_test "operands[2] == const0_rtx")
11786                       (const_string "8")
11787                       (const_string "12")))])
11789 (define_insn_and_split "*neg_ne_<mode>"
11790   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11791         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11792                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11793    (clobber (match_scratch:P 3 "=r"))
11794    (clobber (match_scratch:P 4 "=r"))
11795    (clobber (reg:P CA_REGNO))]
11796   ""
11797   "#"
11798   ""
11799   [(parallel [(set (match_dup 4)
11800                    (neg:P (match_dup 3)))
11801               (set (reg:P CA_REGNO)
11802                    (eq:P (match_dup 3)
11803                          (const_int 0)))])
11804    (parallel [(set (match_dup 0)
11805                    (plus:P (reg:P CA_REGNO)
11806                            (const_int -1)))
11807               (clobber (reg:P CA_REGNO))])]
11809   operands[3] = rs6000_emit_eqne (<MODE>mode,
11810                                   operands[1], operands[2], operands[3]);
11812   if (GET_CODE (operands[4]) == SCRATCH)
11813     operands[4] = gen_reg_rtx (<MODE>mode);
11815   [(set (attr "length")
11816         (if_then_else (match_test "operands[2] == const0_rtx")
11817                       (const_string "8")
11818                       (const_string "12")))])
11820 (define_insn_and_split "*plus_eq_<mode>"
11821   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11822         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11823                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11824                 (match_operand:P 3 "gpc_reg_operand" "r")))
11825    (clobber (match_scratch:P 4 "=r"))
11826    (clobber (match_scratch:P 5 "=r"))
11827    (clobber (reg:P CA_REGNO))]
11828   ""
11829   "#"
11830   ""
11831   [(parallel [(set (match_dup 5)
11832                    (neg:P (match_dup 4)))
11833               (set (reg:P CA_REGNO)
11834                    (eq:P (match_dup 4)
11835                          (const_int 0)))])
11836    (parallel [(set (match_dup 0)
11837                    (plus:P (match_dup 3)
11838                            (reg:P CA_REGNO)))
11839               (clobber (reg:P CA_REGNO))])]
11841   operands[4] = rs6000_emit_eqne (<MODE>mode,
11842                                   operands[1], operands[2], operands[4]);
11844   if (GET_CODE (operands[5]) == SCRATCH)
11845     operands[5] = gen_reg_rtx (<MODE>mode);
11847   [(set (attr "length")
11848         (if_then_else (match_test "operands[2] == const0_rtx")
11849                       (const_string "8")
11850                       (const_string "12")))])
11852 (define_insn_and_split "*plus_ne_<mode>"
11853   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11854         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11855                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11856                 (match_operand:P 3 "gpc_reg_operand" "r")))
11857    (clobber (match_scratch:P 4 "=r"))
11858    (clobber (match_scratch:P 5 "=r"))
11859    (clobber (reg:P CA_REGNO))]
11860   ""
11861   "#"
11862   ""
11863   [(parallel [(set (match_dup 5)
11864                    (plus:P (match_dup 4)
11865                            (const_int -1)))
11866               (set (reg:P CA_REGNO)
11867                    (ne:P (match_dup 4)
11868                          (const_int 0)))])
11869    (parallel [(set (match_dup 0)
11870                    (plus:P (match_dup 3)
11871                            (reg:P CA_REGNO)))
11872               (clobber (reg:P CA_REGNO))])]
11874   operands[4] = rs6000_emit_eqne (<MODE>mode,
11875                                   operands[1], operands[2], operands[4]);
11877   if (GET_CODE (operands[5]) == SCRATCH)
11878     operands[5] = gen_reg_rtx (<MODE>mode);
11880   [(set (attr "length")
11881         (if_then_else (match_test "operands[2] == const0_rtx")
11882                       (const_string "8")
11883                       (const_string "12")))])
11885 (define_insn_and_split "*minus_eq_<mode>"
11886   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11887         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11888                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11889                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11890    (clobber (match_scratch:P 4 "=r"))
11891    (clobber (match_scratch:P 5 "=r"))
11892    (clobber (reg:P CA_REGNO))]
11893   ""
11894   "#"
11895   ""
11896   [(parallel [(set (match_dup 5)
11897                    (plus:P (match_dup 4)
11898                            (const_int -1)))
11899               (set (reg:P CA_REGNO)
11900                    (ne:P (match_dup 4)
11901                          (const_int 0)))])
11902    (parallel [(set (match_dup 0)
11903                    (plus:P (plus:P (match_dup 3)
11904                                    (reg:P CA_REGNO))
11905                            (const_int -1)))
11906               (clobber (reg:P CA_REGNO))])]
11908   operands[4] = rs6000_emit_eqne (<MODE>mode,
11909                                   operands[1], operands[2], operands[4]);
11911   if (GET_CODE (operands[5]) == SCRATCH)
11912     operands[5] = gen_reg_rtx (<MODE>mode);
11914   [(set (attr "length")
11915         (if_then_else (match_test "operands[2] == const0_rtx")
11916                       (const_string "8")
11917                       (const_string "12")))])
11919 (define_insn_and_split "*minus_ne_<mode>"
11920   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11921         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11922                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11923                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11924    (clobber (match_scratch:P 4 "=r"))
11925    (clobber (match_scratch:P 5 "=r"))
11926    (clobber (reg:P CA_REGNO))]
11927   ""
11928   "#"
11929   ""
11930   [(parallel [(set (match_dup 5)
11931                    (neg:P (match_dup 4)))
11932               (set (reg:P CA_REGNO)
11933                    (eq:P (match_dup 4)
11934                          (const_int 0)))])
11935    (parallel [(set (match_dup 0)
11936                    (plus:P (plus:P (match_dup 3)
11937                                    (reg:P CA_REGNO))
11938                            (const_int -1)))
11939               (clobber (reg:P CA_REGNO))])]
11941   operands[4] = rs6000_emit_eqne (<MODE>mode,
11942                                   operands[1], operands[2], operands[4]);
11944   if (GET_CODE (operands[5]) == SCRATCH)
11945     operands[5] = gen_reg_rtx (<MODE>mode);
11947   [(set (attr "length")
11948         (if_then_else (match_test "operands[2] == const0_rtx")
11949                       (const_string "8")
11950                       (const_string "12")))])
11952 (define_insn_and_split "*eqsi3_ext<mode>"
11953   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11954         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11955                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11956    (clobber (match_scratch:SI 3 "=r"))
11957    (clobber (match_scratch:SI 4 "=r"))]
11958   ""
11959   "#"
11960   ""
11961   [(set (match_dup 4)
11962         (clz:SI (match_dup 3)))
11963    (set (match_dup 0)
11964         (zero_extend:EXTSI
11965           (lshiftrt:SI (match_dup 4)
11966                        (const_int 5))))]
11968   operands[3] = rs6000_emit_eqne (SImode,
11969                                   operands[1], operands[2], operands[3]);
11971   if (GET_CODE (operands[4]) == SCRATCH)
11972     operands[4] = gen_reg_rtx (SImode);
11974   [(set (attr "length")
11975         (if_then_else (match_test "operands[2] == const0_rtx")
11976                       (const_string "8")
11977                       (const_string "12")))])
11979 (define_insn_and_split "*nesi3_ext<mode>"
11980   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11981         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11982                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11983    (clobber (match_scratch:SI 3 "=r"))
11984    (clobber (match_scratch:SI 4 "=r"))
11985    (clobber (match_scratch:EXTSI 5 "=r"))]
11986   ""
11987   "#"
11988   ""
11989   [(set (match_dup 4)
11990         (clz:SI (match_dup 3)))
11991    (set (match_dup 5)
11992         (zero_extend:EXTSI
11993           (lshiftrt:SI (match_dup 4)
11994                        (const_int 5))))
11995    (set (match_dup 0)
11996         (xor:EXTSI (match_dup 5)
11997                    (const_int 1)))]
11999   operands[3] = rs6000_emit_eqne (SImode,
12000                                   operands[1], operands[2], operands[3]);
12002   if (GET_CODE (operands[4]) == SCRATCH)
12003     operands[4] = gen_reg_rtx (SImode);
12004   if (GET_CODE (operands[5]) == SCRATCH)
12005     operands[5] = gen_reg_rtx (<MODE>mode);
12007   [(set (attr "length")
12008         (if_then_else (match_test "operands[2] == const0_rtx")
12009                       (const_string "12")
12010                       (const_string "16")))])
12012 ;; Define both directions of branch and return.  If we need a reload
12013 ;; register, we'd rather use CR0 since it is much easier to copy a
12014 ;; register CC value to there.
12016 (define_insn ""
12017   [(set (pc)
12018         (if_then_else (match_operator 1 "branch_comparison_operator"
12019                                       [(match_operand 2
12020                                                       "cc_reg_operand" "y")
12021                                        (const_int 0)])
12022                       (label_ref (match_operand 0 "" ""))
12023                       (pc)))]
12024   ""
12025   "*
12027   return output_cbranch (operands[1], \"%l0\", 0, insn);
12029   [(set_attr "type" "branch")])
12031 (define_insn ""
12032   [(set (pc)
12033         (if_then_else (match_operator 0 "branch_comparison_operator"
12034                                       [(match_operand 1
12035                                                       "cc_reg_operand" "y")
12036                                        (const_int 0)])
12037                       (any_return)
12038                       (pc)))]
12039   "<return_pred>"
12040   "*
12042   return output_cbranch (operands[0], NULL, 0, insn);
12044   [(set_attr "type" "jmpreg")
12045    (set_attr "length" "4")])
12047 (define_insn ""
12048   [(set (pc)
12049         (if_then_else (match_operator 1 "branch_comparison_operator"
12050                                       [(match_operand 2
12051                                                       "cc_reg_operand" "y")
12052                                        (const_int 0)])
12053                       (pc)
12054                       (label_ref (match_operand 0 "" ""))))]
12055   ""
12056   "*
12058   return output_cbranch (operands[1], \"%l0\", 1, insn);
12060   [(set_attr "type" "branch")])
12062 (define_insn ""
12063   [(set (pc)
12064         (if_then_else (match_operator 0 "branch_comparison_operator"
12065                                       [(match_operand 1
12066                                                       "cc_reg_operand" "y")
12067                                        (const_int 0)])
12068                       (pc)
12069                       (any_return)))]
12070   "<return_pred>"
12071   "*
12073   return output_cbranch (operands[0], NULL, 1, insn);
12075   [(set_attr "type" "jmpreg")
12076    (set_attr "length" "4")])
12078 ;; Logic on condition register values.
12080 ; This pattern matches things like
12081 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12082 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12083 ;                                  (const_int 1)))
12084 ; which are generated by the branch logic.
12085 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12087 (define_insn "*cceq_ior_compare"
12088   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12089         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12090                         [(match_operator:SI 2
12091                                       "branch_positive_comparison_operator"
12092                                       [(match_operand 3
12093                                                       "cc_reg_operand" "y,y")
12094                                        (const_int 0)])
12095                          (match_operator:SI 4
12096                                       "branch_positive_comparison_operator"
12097                                       [(match_operand 5
12098                                                       "cc_reg_operand" "0,y")
12099                                        (const_int 0)])])
12100                       (const_int 1)))]
12101   ""
12102   "cr%q1 %E0,%j2,%j4"
12103   [(set_attr "type" "cr_logical,delayed_cr")])
12105 ; Why is the constant -1 here, but 1 in the previous pattern?
12106 ; Because ~1 has all but the low bit set.
12107 (define_insn ""
12108   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12109         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12110                         [(not:SI (match_operator:SI 2
12111                                       "branch_positive_comparison_operator"
12112                                       [(match_operand 3
12113                                                       "cc_reg_operand" "y,y")
12114                                        (const_int 0)]))
12115                          (match_operator:SI 4
12116                                 "branch_positive_comparison_operator"
12117                                 [(match_operand 5
12118                                                 "cc_reg_operand" "0,y")
12119                                  (const_int 0)])])
12120                       (const_int -1)))]
12121   ""
12122   "cr%q1 %E0,%j2,%j4"
12123   [(set_attr "type" "cr_logical,delayed_cr")])
12125 (define_insn "*cceq_rev_compare"
12126   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12127         (compare:CCEQ (match_operator:SI 1
12128                                       "branch_positive_comparison_operator"
12129                                       [(match_operand 2
12130                                                       "cc_reg_operand" "0,y")
12131                                        (const_int 0)])
12132                       (const_int 0)))]
12133   ""
12134   "crnot %E0,%j1"
12135   [(set_attr "type" "cr_logical,delayed_cr")])
12137 ;; If we are comparing the result of two comparisons, this can be done
12138 ;; using creqv or crxor.
12140 (define_insn_and_split ""
12141   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12142         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12143                               [(match_operand 2 "cc_reg_operand" "y")
12144                                (const_int 0)])
12145                       (match_operator 3 "branch_comparison_operator"
12146                               [(match_operand 4 "cc_reg_operand" "y")
12147                                (const_int 0)])))]
12148   ""
12149   "#"
12150   ""
12151   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12152                                     (match_dup 5)))]
12153   "
12155   int positive_1, positive_2;
12157   positive_1 = branch_positive_comparison_operator (operands[1],
12158                                                     GET_MODE (operands[1]));
12159   positive_2 = branch_positive_comparison_operator (operands[3],
12160                                                     GET_MODE (operands[3]));
12162   if (! positive_1)
12163     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12164                                                             GET_CODE (operands[1])),
12165                                   SImode,
12166                                   operands[2], const0_rtx);
12167   else if (GET_MODE (operands[1]) != SImode)
12168     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12169                                   operands[2], const0_rtx);
12171   if (! positive_2)
12172     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12173                                                             GET_CODE (operands[3])),
12174                                   SImode,
12175                                   operands[4], const0_rtx);
12176   else if (GET_MODE (operands[3]) != SImode)
12177     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12178                                   operands[4], const0_rtx);
12180   if (positive_1 == positive_2)
12181     {
12182       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12183       operands[5] = constm1_rtx;
12184     }
12185   else
12186     {
12187       operands[5] = const1_rtx;
12188     }
12191 ;; Unconditional branch and return.
12193 (define_insn "jump"
12194   [(set (pc)
12195         (label_ref (match_operand 0 "" "")))]
12196   ""
12197   "b %l0"
12198   [(set_attr "type" "branch")])
12200 (define_insn "<return_str>return"
12201   [(any_return)]
12202   "<return_pred>"
12203   "blr"
12204   [(set_attr "type" "jmpreg")])
12206 (define_expand "indirect_jump"
12207   [(set (pc) (match_operand 0 "register_operand" ""))])
12209 (define_insn "*indirect_jump<mode>"
12210   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12211   ""
12212   "@
12213    bctr
12214    blr"
12215   [(set_attr "type" "jmpreg")])
12217 ;; Table jump for switch statements:
12218 (define_expand "tablejump"
12219   [(use (match_operand 0 "" ""))
12220    (use (label_ref (match_operand 1 "" "")))]
12221   ""
12222   "
12224   if (TARGET_32BIT)
12225     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12226   else
12227     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12228   DONE;
12231 (define_expand "tablejumpsi"
12232   [(set (match_dup 3)
12233         (plus:SI (match_operand:SI 0 "" "")
12234                  (match_dup 2)))
12235    (parallel [(set (pc) (match_dup 3))
12236               (use (label_ref (match_operand 1 "" "")))])]
12237   "TARGET_32BIT"
12238   "
12239 { operands[0] = force_reg (SImode, operands[0]);
12240   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12241   operands[3] = gen_reg_rtx (SImode);
12244 (define_expand "tablejumpdi"
12245   [(set (match_dup 4)
12246         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12247    (set (match_dup 3)
12248         (plus:DI (match_dup 4)
12249                  (match_dup 2)))
12250    (parallel [(set (pc) (match_dup 3))
12251               (use (label_ref (match_operand 1 "" "")))])]
12252   "TARGET_64BIT"
12253   "
12254 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12255   operands[3] = gen_reg_rtx (DImode);
12256   operands[4] = gen_reg_rtx (DImode);
12259 (define_insn "*tablejump<mode>_internal1"
12260   [(set (pc)
12261         (match_operand:P 0 "register_operand" "c,*l"))
12262    (use (label_ref (match_operand 1 "" "")))]
12263   ""
12264   "@
12265    bctr
12266    blr"
12267   [(set_attr "type" "jmpreg")])
12269 (define_insn "nop"
12270   [(unspec [(const_int 0)] UNSPEC_NOP)]
12271   ""
12272   "nop")
12274 (define_insn "group_ending_nop"
12275   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12276   ""
12277   "*
12279   if (rs6000_cpu_attr == CPU_POWER6)
12280     return \"ori 1,1,0\";
12281   return \"ori 2,2,0\";
12284 ;; Define the subtract-one-and-jump insns, starting with the template
12285 ;; so loop.c knows what to generate.
12287 (define_expand "doloop_end"
12288   [(use (match_operand 0 "" ""))        ; loop pseudo
12289    (use (match_operand 1 "" ""))]       ; label
12290   ""
12291   "
12293   if (TARGET_64BIT)
12294     {
12295       if (GET_MODE (operands[0]) != DImode)
12296         FAIL;
12297       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12298     }
12299   else
12300     {
12301       if (GET_MODE (operands[0]) != SImode)
12302         FAIL;
12303       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12304     }
12305   DONE;
12308 (define_expand "ctr<mode>"
12309   [(parallel [(set (pc)
12310                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12311                                      (const_int 1))
12312                                  (label_ref (match_operand 1 "" ""))
12313                                  (pc)))
12314               (set (match_dup 0)
12315                    (plus:P (match_dup 0)
12316                             (const_int -1)))
12317               (unspec [(const_int 0)] UNSPEC_DOLOOP)
12318               (clobber (match_scratch:CC 2 ""))
12319               (clobber (match_scratch:P 3 ""))])]
12320   ""
12321   "")
12323 ;; We need to be able to do this for any operand, including MEM, or we
12324 ;; will cause reload to blow up since we don't allow output reloads on
12325 ;; JUMP_INSNs.
12326 ;; For the length attribute to be calculated correctly, the
12327 ;; label MUST be operand 0.
12328 ;; The UNSPEC is present to prevent combine creating this pattern.
12330 (define_insn "*ctr<mode>_internal1"
12331   [(set (pc)
12332         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12333                           (const_int 1))
12334                       (label_ref (match_operand 0 "" ""))
12335                       (pc)))
12336    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12337         (plus:P (match_dup 1)
12338                  (const_int -1)))
12339    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12340    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12341    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12342   ""
12343   "*
12345   if (which_alternative != 0)
12346     return \"#\";
12347   else if (get_attr_length (insn) == 4)
12348     return \"bdnz %l0\";
12349   else
12350     return \"bdz $+8\;b %l0\";
12352   [(set_attr "type" "branch")
12353    (set_attr "length" "*,16,20,20")])
12355 (define_insn "*ctr<mode>_internal2"
12356   [(set (pc)
12357         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12358                           (const_int 1))
12359                       (pc)
12360                       (label_ref (match_operand 0 "" ""))))
12361    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12362         (plus:P (match_dup 1)
12363                  (const_int -1)))
12364    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12365    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12366    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12367   ""
12368   "*
12370   if (which_alternative != 0)
12371     return \"#\";
12372   else if (get_attr_length (insn) == 4)
12373     return \"bdz %l0\";
12374   else
12375     return \"bdnz $+8\;b %l0\";
12377   [(set_attr "type" "branch")
12378    (set_attr "length" "*,16,20,20")])
12380 ;; Similar but use EQ
12382 (define_insn "*ctr<mode>_internal5"
12383   [(set (pc)
12384         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12385                           (const_int 1))
12386                       (label_ref (match_operand 0 "" ""))
12387                       (pc)))
12388    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12389         (plus:P (match_dup 1)
12390                  (const_int -1)))
12391    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12392    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12393    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12394   ""
12395   "*
12397   if (which_alternative != 0)
12398     return \"#\";
12399   else if (get_attr_length (insn) == 4)
12400     return \"bdz %l0\";
12401   else
12402     return \"bdnz $+8\;b %l0\";
12404   [(set_attr "type" "branch")
12405    (set_attr "length" "*,16,20,20")])
12407 (define_insn "*ctr<mode>_internal6"
12408   [(set (pc)
12409         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12410                           (const_int 1))
12411                       (pc)
12412                       (label_ref (match_operand 0 "" ""))))
12413    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12414         (plus:P (match_dup 1)
12415                  (const_int -1)))
12416    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12417    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12418    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12419   ""
12420   "*
12422   if (which_alternative != 0)
12423     return \"#\";
12424   else if (get_attr_length (insn) == 4)
12425     return \"bdnz %l0\";
12426   else
12427     return \"bdz $+8\;b %l0\";
12429   [(set_attr "type" "branch")
12430    (set_attr "length" "*,16,20,20")])
12432 ;; Now the splitters if we could not allocate the CTR register
12434 (define_split
12435   [(set (pc)
12436         (if_then_else (match_operator 2 "comparison_operator"
12437                                       [(match_operand:P 1 "gpc_reg_operand" "")
12438                                        (const_int 1)])
12439                       (match_operand 5 "" "")
12440                       (match_operand 6 "" "")))
12441    (set (match_operand:P 0 "int_reg_operand" "")
12442         (plus:P (match_dup 1) (const_int -1)))
12443    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12444    (clobber (match_scratch:CC 3 ""))
12445    (clobber (match_scratch:P 4 ""))]
12446   "reload_completed"
12447   [(set (match_dup 3)
12448         (compare:CC (match_dup 1)
12449                     (const_int 1)))
12450    (set (match_dup 0)
12451         (plus:P (match_dup 1)
12452                 (const_int -1)))
12453    (set (pc) (if_then_else (match_dup 7)
12454                            (match_dup 5)
12455                            (match_dup 6)))]
12456   "
12457 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12458                                 operands[3], const0_rtx); }")
12460 (define_split
12461   [(set (pc)
12462         (if_then_else (match_operator 2 "comparison_operator"
12463                                       [(match_operand:P 1 "gpc_reg_operand" "")
12464                                        (const_int 1)])
12465                       (match_operand 5 "" "")
12466                       (match_operand 6 "" "")))
12467    (set (match_operand:P 0 "nonimmediate_operand" "")
12468         (plus:P (match_dup 1) (const_int -1)))
12469    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12470    (clobber (match_scratch:CC 3 ""))
12471    (clobber (match_scratch:P 4 ""))]
12472   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12473   [(set (match_dup 3)
12474         (compare:CC (match_dup 1)
12475                     (const_int 1)))
12476    (set (match_dup 4)
12477         (plus:P (match_dup 1)
12478                 (const_int -1)))
12479    (set (match_dup 0)
12480         (match_dup 4))
12481    (set (pc) (if_then_else (match_dup 7)
12482                            (match_dup 5)
12483                            (match_dup 6)))]
12484   "
12485 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12486                                 operands[3], const0_rtx); }")
12488 (define_insn "trap"
12489   [(trap_if (const_int 1) (const_int 0))]
12490   ""
12491   "trap"
12492   [(set_attr "type" "trap")])
12494 (define_expand "ctrap<mode>4"
12495   [(trap_if (match_operator 0 "ordered_comparison_operator"
12496                             [(match_operand:GPR 1 "register_operand")
12497                              (match_operand:GPR 2 "reg_or_short_operand")])
12498             (match_operand 3 "zero_constant" ""))]
12499   ""
12500   "")
12502 (define_insn ""
12503   [(trap_if (match_operator 0 "ordered_comparison_operator"
12504                             [(match_operand:GPR 1 "register_operand" "r")
12505                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12506             (const_int 0))]
12507   ""
12508   "t<wd>%V0%I2 %1,%2"
12509   [(set_attr "type" "trap")])
12511 ;; Insns related to generating the function prologue and epilogue.
12513 (define_expand "prologue"
12514   [(use (const_int 0))]
12515   ""
12517   rs6000_emit_prologue ();
12518   if (!TARGET_SCHED_PROLOG)
12519     emit_insn (gen_blockage ());
12520   DONE;
12523 (define_insn "*movesi_from_cr_one"
12524   [(match_parallel 0 "mfcr_operation"
12525                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12526                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12527                                      (match_operand 3 "immediate_operand" "n")]
12528                           UNSPEC_MOVESI_FROM_CR))])]
12529   "TARGET_MFCRF"
12530   "*
12532   int mask = 0;
12533   int i;
12534   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12535   {
12536     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12537     operands[4] = GEN_INT (mask);
12538     output_asm_insn (\"mfcr %1,%4\", operands);
12539   }
12540   return \"\";
12542   [(set_attr "type" "mfcrf")])
12544 (define_insn "movesi_from_cr"
12545   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12546         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12547                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12548                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12549                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12550                    UNSPEC_MOVESI_FROM_CR))]
12551   ""
12552   "mfcr %0"
12553   [(set_attr "type" "mfcr")])
12555 (define_insn "*crsave"
12556   [(match_parallel 0 "crsave_operation"
12557                    [(set (match_operand:SI 1 "memory_operand" "=m")
12558                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12559   ""
12560   "stw %2,%1"
12561   [(set_attr "type" "store")])
12563 (define_insn "*stmw"
12564   [(match_parallel 0 "stmw_operation"
12565                    [(set (match_operand:SI 1 "memory_operand" "=m")
12566                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12567   "TARGET_MULTIPLE"
12568   "stmw %2,%1"
12569   [(set_attr "type" "store")
12570    (set_attr "update" "yes")
12571    (set_attr "indexed" "yes")])
12573 ; The following comment applies to:
12574 ;     save_gpregs_*
12575 ;     save_fpregs_*
12576 ;     restore_gpregs*
12577 ;     return_and_restore_gpregs*
12578 ;     return_and_restore_fpregs*
12579 ;     return_and_restore_fpregs_aix*
12581 ; The out-of-line save / restore functions expects one input argument.
12582 ; Since those are not standard call_insn's, we must avoid using
12583 ; MATCH_OPERAND for that argument. That way the register rename
12584 ; optimization will not try to rename this register.
12585 ; Each pattern is repeated for each possible register number used in 
12586 ; various ABIs (r11, r1, and for some functions r12)
12588 (define_insn "*save_gpregs_<mode>_r11"
12589   [(match_parallel 0 "any_parallel_operand"
12590                    [(clobber (reg:P LR_REGNO))
12591                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12592                     (use (reg:P 11))
12593                     (set (match_operand:P 2 "memory_operand" "=m")
12594                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12595   ""
12596   "bl %1"
12597   [(set_attr "type" "branch")
12598    (set_attr "length" "4")])
12600 (define_insn "*save_gpregs_<mode>_r12"
12601   [(match_parallel 0 "any_parallel_operand"
12602                    [(clobber (reg:P LR_REGNO))
12603                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12604                     (use (reg:P 12))
12605                     (set (match_operand:P 2 "memory_operand" "=m")
12606                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12607   ""
12608   "bl %1"
12609   [(set_attr "type" "branch")
12610    (set_attr "length" "4")])
12612 (define_insn "*save_gpregs_<mode>_r1"
12613   [(match_parallel 0 "any_parallel_operand"
12614                    [(clobber (reg:P LR_REGNO))
12615                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12616                     (use (reg:P 1))
12617                     (set (match_operand:P 2 "memory_operand" "=m")
12618                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12619   ""
12620   "bl %1"
12621   [(set_attr "type" "branch")
12622    (set_attr "length" "4")])
12624 (define_insn "*save_fpregs_<mode>_r11"
12625   [(match_parallel 0 "any_parallel_operand"
12626                    [(clobber (reg:P LR_REGNO))
12627                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12628                     (use (reg:P 11))
12629                     (set (match_operand:DF 2 "memory_operand" "=m")
12630                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12631   ""
12632   "bl %1"
12633   [(set_attr "type" "branch")
12634    (set_attr "length" "4")])
12636 (define_insn "*save_fpregs_<mode>_r12"
12637   [(match_parallel 0 "any_parallel_operand"
12638                    [(clobber (reg:P LR_REGNO))
12639                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12640                     (use (reg:P 12))
12641                     (set (match_operand:DF 2 "memory_operand" "=m")
12642                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12643   ""
12644   "bl %1"
12645   [(set_attr "type" "branch")
12646    (set_attr "length" "4")])
12648 (define_insn "*save_fpregs_<mode>_r1"
12649   [(match_parallel 0 "any_parallel_operand"
12650                    [(clobber (reg:P LR_REGNO))
12651                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12652                     (use (reg:P 1))
12653                     (set (match_operand:DF 2 "memory_operand" "=m")
12654                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12655   ""
12656   "bl %1"
12657   [(set_attr "type" "branch")
12658    (set_attr "length" "4")])
12660 ; This is to explain that changes to the stack pointer should
12661 ; not be moved over loads from or stores to stack memory.
12662 (define_insn "stack_tie"
12663   [(match_parallel 0 "tie_operand"
12664                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12665   ""
12666   ""
12667   [(set_attr "length" "0")])
12669 (define_expand "epilogue"
12670   [(use (const_int 0))]
12671   ""
12673   if (!TARGET_SCHED_PROLOG)
12674     emit_insn (gen_blockage ());
12675   rs6000_emit_epilogue (FALSE);
12676   DONE;
12679 ; On some processors, doing the mtcrf one CC register at a time is
12680 ; faster (like on the 604e).  On others, doing them all at once is
12681 ; faster; for instance, on the 601 and 750.
12683 (define_expand "movsi_to_cr_one"
12684   [(set (match_operand:CC 0 "cc_reg_operand" "")
12685         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12686                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12687   ""
12688   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12690 (define_insn "*movsi_to_cr"
12691   [(match_parallel 0 "mtcrf_operation"
12692                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12693                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12694                                      (match_operand 3 "immediate_operand" "n")]
12695                                     UNSPEC_MOVESI_TO_CR))])]
12696  ""
12697  "*
12699   int mask = 0;
12700   int i;
12701   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12702     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12703   operands[4] = GEN_INT (mask);
12704   return \"mtcrf %4,%2\";
12706   [(set_attr "type" "mtcr")])
12708 (define_insn "*mtcrfsi"
12709   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12710         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12711                     (match_operand 2 "immediate_operand" "n")]
12712                    UNSPEC_MOVESI_TO_CR))]
12713   "GET_CODE (operands[0]) == REG
12714    && CR_REGNO_P (REGNO (operands[0]))
12715    && GET_CODE (operands[2]) == CONST_INT
12716    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12717   "mtcrf %R0,%1"
12718   [(set_attr "type" "mtcr")])
12720 ; The load-multiple instructions have similar properties.
12721 ; Note that "load_multiple" is a name known to the machine-independent
12722 ; code that actually corresponds to the PowerPC load-string.
12724 (define_insn "*lmw"
12725   [(match_parallel 0 "lmw_operation"
12726                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12727                          (match_operand:SI 2 "memory_operand" "m"))])]
12728   "TARGET_MULTIPLE"
12729   "lmw %1,%2"
12730   [(set_attr "type" "load")
12731    (set_attr "update" "yes")
12732    (set_attr "indexed" "yes")
12733    (set_attr "cell_micro" "always")])
12735 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12736 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12738 ; The following comment applies to:
12739 ;     save_gpregs_*
12740 ;     save_fpregs_*
12741 ;     restore_gpregs*
12742 ;     return_and_restore_gpregs*
12743 ;     return_and_restore_fpregs*
12744 ;     return_and_restore_fpregs_aix*
12746 ; The out-of-line save / restore functions expects one input argument.
12747 ; Since those are not standard call_insn's, we must avoid using
12748 ; MATCH_OPERAND for that argument. That way the register rename
12749 ; optimization will not try to rename this register.
12750 ; Each pattern is repeated for each possible register number used in 
12751 ; various ABIs (r11, r1, and for some functions r12)
12753 (define_insn "*restore_gpregs_<mode>_r11"
12754  [(match_parallel 0 "any_parallel_operand"
12755                   [(clobber (reg:P LR_REGNO))
12756                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12757                    (use (reg:P 11))
12758                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12759                         (match_operand:P 3 "memory_operand" "m"))])]
12760  ""
12761  "bl %1"
12762  [(set_attr "type" "branch")
12763   (set_attr "length" "4")])
12765 (define_insn "*restore_gpregs_<mode>_r12"
12766  [(match_parallel 0 "any_parallel_operand"
12767                   [(clobber (reg:P LR_REGNO))
12768                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12769                    (use (reg:P 12))
12770                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12771                         (match_operand:P 3 "memory_operand" "m"))])]
12772  ""
12773  "bl %1"
12774  [(set_attr "type" "branch")
12775   (set_attr "length" "4")])
12777 (define_insn "*restore_gpregs_<mode>_r1"
12778  [(match_parallel 0 "any_parallel_operand"
12779                   [(clobber (reg:P LR_REGNO))
12780                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12781                    (use (reg:P 1))
12782                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12783                         (match_operand:P 3 "memory_operand" "m"))])]
12784  ""
12785  "bl %1"
12786  [(set_attr "type" "branch")
12787   (set_attr "length" "4")])
12789 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12790  [(match_parallel 0 "any_parallel_operand"
12791                   [(return)
12792                    (clobber (reg:P LR_REGNO))
12793                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12794                    (use (reg:P 11))
12795                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12796                         (match_operand:P 3 "memory_operand" "m"))])]
12797  ""
12798  "b %1"
12799  [(set_attr "type" "branch")
12800   (set_attr "length" "4")])
12802 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12803  [(match_parallel 0 "any_parallel_operand"
12804                   [(return)
12805                    (clobber (reg:P LR_REGNO))
12806                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12807                    (use (reg:P 12))
12808                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12809                         (match_operand:P 3 "memory_operand" "m"))])]
12810  ""
12811  "b %1"
12812  [(set_attr "type" "branch")
12813   (set_attr "length" "4")])
12815 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12816  [(match_parallel 0 "any_parallel_operand"
12817                   [(return)
12818                    (clobber (reg:P LR_REGNO))
12819                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12820                    (use (reg:P 1))
12821                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12822                         (match_operand:P 3 "memory_operand" "m"))])]
12823  ""
12824  "b %1"
12825  [(set_attr "type" "branch")
12826   (set_attr "length" "4")])
12828 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12829  [(match_parallel 0 "any_parallel_operand"
12830                   [(return)
12831                    (clobber (reg:P LR_REGNO))
12832                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12833                    (use (reg:P 11))
12834                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12835                         (match_operand:DF 3 "memory_operand" "m"))])]
12836  ""
12837  "b %1"
12838  [(set_attr "type" "branch")
12839   (set_attr "length" "4")])
12841 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12842  [(match_parallel 0 "any_parallel_operand"
12843                   [(return)
12844                    (clobber (reg:P LR_REGNO))
12845                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12846                    (use (reg:P 12))
12847                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12848                         (match_operand:DF 3 "memory_operand" "m"))])]
12849  ""
12850  "b %1"
12851  [(set_attr "type" "branch")
12852   (set_attr "length" "4")])
12854 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12855  [(match_parallel 0 "any_parallel_operand"
12856                   [(return)
12857                    (clobber (reg:P LR_REGNO))
12858                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12859                    (use (reg:P 1))
12860                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12861                         (match_operand:DF 3 "memory_operand" "m"))])]
12862  ""
12863  "b %1"
12864  [(set_attr "type" "branch")
12865   (set_attr "length" "4")])
12867 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12868  [(match_parallel 0 "any_parallel_operand"
12869                   [(return)
12870                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12871                    (use (reg:P 11))
12872                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12873                         (match_operand:DF 3 "memory_operand" "m"))])]
12874  ""
12875  "b %1"
12876  [(set_attr "type" "branch")
12877   (set_attr "length" "4")])
12879 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12880  [(match_parallel 0 "any_parallel_operand"
12881                   [(return)
12882                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12883                    (use (reg:P 1))
12884                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12885                         (match_operand:DF 3 "memory_operand" "m"))])]
12886  ""
12887  "b %1"
12888  [(set_attr "type" "branch")
12889   (set_attr "length" "4")])
12891 ; This is used in compiling the unwind routines.
12892 (define_expand "eh_return"
12893   [(use (match_operand 0 "general_operand" ""))]
12894   ""
12895   "
12897   if (TARGET_32BIT)
12898     emit_insn (gen_eh_set_lr_si (operands[0]));
12899   else
12900     emit_insn (gen_eh_set_lr_di (operands[0]));
12901   DONE;
12904 ; We can't expand this before we know where the link register is stored.
12905 (define_insn "eh_set_lr_<mode>"
12906   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12907                     UNSPECV_EH_RR)
12908    (clobber (match_scratch:P 1 "=&b"))]
12909   ""
12910   "#")
12912 (define_split
12913   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12914    (clobber (match_scratch 1 ""))]
12915   "reload_completed"
12916   [(const_int 0)]
12917   "
12919   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12920   DONE;
12923 (define_insn "prefetch"
12924   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12925              (match_operand:SI 1 "const_int_operand" "n")
12926              (match_operand:SI 2 "const_int_operand" "n"))]
12927   ""
12928   "*
12930   if (GET_CODE (operands[0]) == REG)
12931     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12932   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12934   [(set_attr "type" "load")])
12936 ;; Handle -fsplit-stack.
12938 (define_expand "split_stack_prologue"
12939   [(const_int 0)]
12940   ""
12942   rs6000_expand_split_stack_prologue ();
12943   DONE;
12946 (define_expand "load_split_stack_limit"
12947   [(set (match_operand 0)
12948         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12949   ""
12951   emit_insn (gen_rtx_SET (operands[0],
12952                           gen_rtx_UNSPEC (Pmode,
12953                                           gen_rtvec (1, const0_rtx),
12954                                           UNSPEC_STACK_CHECK)));
12955   DONE;
12958 (define_insn "load_split_stack_limit_di"
12959   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12960         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12961   "TARGET_64BIT"
12962   "ld %0,-0x7040(13)"
12963   [(set_attr "type" "load")
12964    (set_attr "update" "no")
12965    (set_attr "indexed" "no")])
12967 (define_insn "load_split_stack_limit_si"
12968   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12969         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12970   "!TARGET_64BIT"
12971   "lwz %0,-0x7020(2)"
12972   [(set_attr "type" "load")
12973    (set_attr "update" "no")
12974    (set_attr "indexed" "no")])
12976 ;; A return instruction which the middle-end doesn't see.
12977 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12978 ;; after the call to __morestack.
12979 (define_insn "split_stack_return"
12980   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12981   ""
12982   "blr"
12983   [(set_attr "type" "jmpreg")])
12985 ;; If there are operand 0 bytes available on the stack, jump to
12986 ;; operand 1.
12987 (define_expand "split_stack_space_check"
12988   [(set (match_dup 2)
12989         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12990    (set (match_dup 3)
12991         (minus (reg STACK_POINTER_REGNUM)
12992                (match_operand 0)))
12993    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12994    (set (pc) (if_then_else
12995               (geu (match_dup 4) (const_int 0))
12996               (label_ref (match_operand 1))
12997               (pc)))]
12998   ""
13000   rs6000_split_stack_space_check (operands[0], operands[1]);
13001   DONE;
13004 (define_insn "bpermd_<mode>"
13005   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13006         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13007                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13008   "TARGET_POPCNTD"
13009   "bpermd %0,%1,%2"
13010   [(set_attr "type" "popcnt")])
13013 ;; Builtin fma support.  Handle 
13014 ;; Note that the conditions for expansion are in the FMA_F iterator.
13016 (define_expand "fma<mode>4"
13017   [(set (match_operand:FMA_F 0 "register_operand" "")
13018         (fma:FMA_F
13019           (match_operand:FMA_F 1 "register_operand" "")
13020           (match_operand:FMA_F 2 "register_operand" "")
13021           (match_operand:FMA_F 3 "register_operand" "")))]
13022   ""
13023   "")
13025 (define_insn "*fma<mode>4_fpr"
13026   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13027         (fma:SFDF
13028           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13029           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13030           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13031   "TARGET_<MODE>_FPR"
13032   "@
13033    fmadd<Ftrad> %0,%1,%2,%3
13034    xsmadda<Fvsx> %x0,%x1,%x2
13035    xsmaddm<Fvsx> %x0,%x1,%x3"
13036   [(set_attr "type" "fp")
13037    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13039 ; Altivec only has fma and nfms.
13040 (define_expand "fms<mode>4"
13041   [(set (match_operand:FMA_F 0 "register_operand" "")
13042         (fma:FMA_F
13043           (match_operand:FMA_F 1 "register_operand" "")
13044           (match_operand:FMA_F 2 "register_operand" "")
13045           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
13046   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13047   "")
13049 (define_insn "*fms<mode>4_fpr"
13050   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13051         (fma:SFDF
13052          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13053          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13054          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13055   "TARGET_<MODE>_FPR"
13056   "@
13057    fmsub<Ftrad> %0,%1,%2,%3
13058    xsmsuba<Fvsx> %x0,%x1,%x2
13059    xsmsubm<Fvsx> %x0,%x1,%x3"
13060   [(set_attr "type" "fp")
13061    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13063 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13064 (define_expand "fnma<mode>4"
13065   [(set (match_operand:FMA_F 0 "register_operand" "")
13066         (neg:FMA_F
13067           (fma:FMA_F
13068             (match_operand:FMA_F 1 "register_operand" "")
13069             (match_operand:FMA_F 2 "register_operand" "")
13070             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13071   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13072   "")
13074 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13075 (define_expand "fnms<mode>4"
13076   [(set (match_operand:FMA_F 0 "register_operand" "")
13077         (neg:FMA_F
13078           (fma:FMA_F
13079             (match_operand:FMA_F 1 "register_operand" "")
13080             (match_operand:FMA_F 2 "register_operand" "")
13081             (match_operand:FMA_F 3 "register_operand" ""))))]
13082   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13083   "")
13085 ; Not an official optab name, but used from builtins.
13086 (define_expand "nfma<mode>4"
13087   [(set (match_operand:FMA_F 0 "register_operand" "")
13088         (neg:FMA_F
13089           (fma:FMA_F
13090             (match_operand:FMA_F 1 "register_operand" "")
13091             (match_operand:FMA_F 2 "register_operand" "")
13092             (match_operand:FMA_F 3 "register_operand" ""))))]
13093   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13094   "")
13096 (define_insn "*nfma<mode>4_fpr"
13097   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13098         (neg:SFDF
13099          (fma:SFDF
13100           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13101           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13102           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13103   "TARGET_<MODE>_FPR"
13104   "@
13105    fnmadd<Ftrad> %0,%1,%2,%3
13106    xsnmadda<Fvsx> %x0,%x1,%x2
13107    xsnmaddm<Fvsx> %x0,%x1,%x3"
13108   [(set_attr "type" "fp")
13109    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13111 ; Not an official optab name, but used from builtins.
13112 (define_expand "nfms<mode>4"
13113   [(set (match_operand:FMA_F 0 "register_operand" "")
13114         (neg:FMA_F
13115           (fma:FMA_F
13116             (match_operand:FMA_F 1 "register_operand" "")
13117             (match_operand:FMA_F 2 "register_operand" "")
13118             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13119   ""
13120   "")
13122 (define_insn "*nfmssf4_fpr"
13123   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13124         (neg:SFDF
13125          (fma:SFDF
13126           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13127           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13128           (neg:SFDF
13129            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13130   "TARGET_<MODE>_FPR"
13131   "@
13132    fnmsub<Ftrad> %0,%1,%2,%3
13133    xsnmsuba<Fvsx> %x0,%x1,%x2
13134    xsnmsubm<Fvsx> %x0,%x1,%x3"
13135   [(set_attr "type" "fp")
13136    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13139 (define_expand "rs6000_get_timebase"
13140   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13141   ""
13143   if (TARGET_POWERPC64)
13144     emit_insn (gen_rs6000_mftb_di (operands[0]));
13145   else
13146     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13147   DONE;
13150 (define_insn "rs6000_get_timebase_ppc32"
13151   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13152         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13153    (clobber (match_scratch:SI 1 "=r"))
13154    (clobber (match_scratch:CC 2 "=y"))]
13155   "!TARGET_POWERPC64"
13157   if (WORDS_BIG_ENDIAN)
13158     if (TARGET_MFCRF)
13159       {
13160         return "mfspr %0,269\;"
13161                "mfspr %L0,268\;"
13162                "mfspr %1,269\;"
13163                "cmpw %2,%0,%1\;"
13164                "bne- %2,$-16";
13165       }
13166     else
13167       {
13168         return "mftbu %0\;"
13169                "mftb %L0\;"
13170                "mftbu %1\;"
13171                "cmpw %2,%0,%1\;"
13172                "bne- %2,$-16";
13173       }
13174   else
13175     if (TARGET_MFCRF)
13176       {
13177         return "mfspr %L0,269\;"
13178                "mfspr %0,268\;"
13179                "mfspr %1,269\;"
13180                "cmpw %2,%L0,%1\;"
13181                "bne- %2,$-16";
13182       }
13183     else
13184       {
13185         return "mftbu %L0\;"
13186                "mftb %0\;"
13187                "mftbu %1\;"
13188                "cmpw %2,%L0,%1\;"
13189                "bne- %2,$-16";
13190       }
13192   [(set_attr "length" "20")])
13194 (define_insn "rs6000_mftb_<mode>"
13195   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13196         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13197   ""
13199   if (TARGET_MFCRF)
13200     return "mfspr %0,268";
13201   else
13202     return "mftb %0";
13206 (define_insn "rs6000_mffs"
13207   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13208         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13209   "TARGET_HARD_FLOAT && TARGET_FPRS"
13210   "mffs %0")
13212 (define_insn "rs6000_mtfsf"
13213   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13214                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13215                     UNSPECV_MTFSF)]
13216   "TARGET_HARD_FLOAT && TARGET_FPRS"
13217   "mtfsf %0,%1")
13220 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13221 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13222 ;; register that is being loaded.  The fused ops must be physically adjacent.
13224 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13225 ;; before register allocation, and is meant to reduce the lifetime for the
13226 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13227 ;; to use the register that is being load.  The peephole2 then gathers any
13228 ;; other fused possibilities that it can find after register allocation.  If
13229 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13231 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13232 ;; before register allocation, so that we can avoid allocating a temporary base
13233 ;; register that won't be used, and that we try to load into base registers,
13234 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13235 ;; (addis followed by load) even on power8.
13237 (define_split
13238   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13239         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13240   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13241   [(parallel [(set (match_dup 0) (match_dup 2))
13242               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13243               (use (match_dup 3))
13244               (clobber (scratch:DI))])]
13246   operands[2] = fusion_wrap_memory_address (operands[1]);
13247   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13250 (define_insn "*toc_fusionload_<mode>"
13251   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13252         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13253    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13254    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13255    (clobber (match_scratch:DI 3 "=X,&b"))]
13256   "TARGET_TOC_FUSION_INT"
13258   if (base_reg_operand (operands[0], <MODE>mode))
13259     return emit_fusion_gpr_load (operands[0], operands[1]);
13261   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13263   [(set_attr "type" "load")
13264    (set_attr "length" "8")])
13266 (define_insn "*toc_fusionload_di"
13267   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13268         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13269    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13270    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13271    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13272   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13273    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13275   if (base_reg_operand (operands[0], DImode))
13276     return emit_fusion_gpr_load (operands[0], operands[1]);
13278   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13280   [(set_attr "type" "load")
13281    (set_attr "length" "8")])
13284 ;; Find cases where the addis that feeds into a load instruction is either used
13285 ;; once or is the same as the target register, and replace it with the fusion
13286 ;; insn
13288 (define_peephole2
13289   [(set (match_operand:P 0 "base_reg_operand" "")
13290         (match_operand:P 1 "fusion_gpr_addis" ""))
13291    (set (match_operand:INT1 2 "base_reg_operand" "")
13292         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13293   "TARGET_P8_FUSION
13294    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13295                          operands[3])"
13296   [(const_int 0)]
13298   expand_fusion_gpr_load (operands);
13299   DONE;
13302 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13303 ;; reload)
13305 (define_insn "fusion_gpr_load_<mode>"
13306   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13307         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13308                      UNSPEC_FUSION_GPR))]
13309   "TARGET_P8_FUSION"
13311   return emit_fusion_gpr_load (operands[0], operands[1]);
13313   [(set_attr "type" "load")
13314    (set_attr "length" "8")])
13317 ;; ISA 3.0 (power9) fusion support
13318 ;; Merge addis with floating load/store to FPRs (or GPRs).
13319 (define_peephole2
13320   [(set (match_operand:P 0 "base_reg_operand" "")
13321         (match_operand:P 1 "fusion_gpr_addis" ""))
13322    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13323         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13324   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13325    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13326   [(const_int 0)]
13328   expand_fusion_p9_load (operands);
13329   DONE;
13332 (define_peephole2
13333   [(set (match_operand:P 0 "base_reg_operand" "")
13334         (match_operand:P 1 "fusion_gpr_addis" ""))
13335    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13336         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13337   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13338    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13339   [(const_int 0)]
13341   expand_fusion_p9_store (operands);
13342   DONE;
13345 (define_peephole2
13346   [(set (match_operand:SDI 0 "int_reg_operand" "")
13347         (match_operand:SDI 1 "upper16_cint_operand" ""))
13348    (set (match_dup 0)
13349         (ior:SDI (match_dup 0)
13350                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13351   "TARGET_P9_FUSION"
13352   [(set (match_dup 0)
13353         (unspec:SDI [(match_dup 1)
13354                      (match_dup 2)] UNSPEC_FUSION_P9))])
13356 (define_peephole2
13357   [(set (match_operand:SDI 0 "int_reg_operand" "")
13358         (match_operand:SDI 1 "upper16_cint_operand" ""))
13359    (set (match_operand:SDI 2 "int_reg_operand" "")
13360         (ior:SDI (match_dup 0)
13361                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13362   "TARGET_P9_FUSION
13363    && !rtx_equal_p (operands[0], operands[2])
13364    && peep2_reg_dead_p (2, operands[0])"
13365   [(set (match_dup 2)
13366         (unspec:SDI [(match_dup 1)
13367                      (match_dup 3)] UNSPEC_FUSION_P9))])
13369 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13370 ;; reload).  Because we want to eventually have secondary_reload generate
13371 ;; these, they have to have a single alternative that gives the register
13372 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13373 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13374   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13375         (unspec:GPR_FUSION
13376          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13377          UNSPEC_FUSION_P9))
13378    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13379   "TARGET_P9_FUSION"
13381   /* This insn is a secondary reload insn, which cannot have alternatives.
13382      If we are not loading up register 0, use the power8 fusion instead.  */
13383   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13384     return emit_fusion_gpr_load (operands[0], operands[1]);
13386   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13388   [(set_attr "type" "load")
13389    (set_attr "length" "8")])
13391 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13392   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13393         (unspec:GPR_FUSION
13394          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13395          UNSPEC_FUSION_P9))
13396    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13397   "TARGET_P9_FUSION"
13399   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13401   [(set_attr "type" "store")
13402    (set_attr "length" "8")])
13404 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13405   [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13406         (unspec:FPR_FUSION
13407          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13408          UNSPEC_FUSION_P9))
13409    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13410   "TARGET_P9_FUSION"
13412   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13414   [(set_attr "type" "fpload")
13415    (set_attr "length" "8")])
13417 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13418   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13419         (unspec:FPR_FUSION
13420          [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13421          UNSPEC_FUSION_P9))
13422    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13423   "TARGET_P9_FUSION"
13425   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13427   [(set_attr "type" "fpstore")
13428    (set_attr "length" "8")])
13430 (define_insn "*fusion_p9_<mode>_constant"
13431   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13432         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13433                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13434                     UNSPEC_FUSION_P9))] 
13435   "TARGET_P9_FUSION"
13437   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13438   return "ori %0,%0,%2";
13440   [(set_attr "type" "two")
13441    (set_attr "length" "8")])
13444 ;; Miscellaneous ISA 2.06 (power7) instructions
13445 (define_insn "addg6s"
13446   [(set (match_operand:SI 0 "register_operand" "=r")
13447         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13448                     (match_operand:SI 2 "register_operand" "r")]
13449                    UNSPEC_ADDG6S))]
13450   "TARGET_POPCNTD"
13451   "addg6s %0,%1,%2"
13452   [(set_attr "type" "integer")
13453    (set_attr "length" "4")])
13455 (define_insn "cdtbcd"
13456   [(set (match_operand:SI 0 "register_operand" "=r")
13457         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13458                    UNSPEC_CDTBCD))]
13459   "TARGET_POPCNTD"
13460   "cdtbcd %0,%1"
13461   [(set_attr "type" "integer")
13462    (set_attr "length" "4")])
13464 (define_insn "cbcdtd"
13465   [(set (match_operand:SI 0 "register_operand" "=r")
13466         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13467                    UNSPEC_CBCDTD))]
13468   "TARGET_POPCNTD"
13469   "cbcdtd %0,%1"
13470   [(set_attr "type" "integer")
13471    (set_attr "length" "4")])
13473 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13474                                         UNSPEC_DIVEO
13475                                         UNSPEC_DIVEU
13476                                         UNSPEC_DIVEUO])
13478 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13479                              (UNSPEC_DIVEO      "eo")
13480                              (UNSPEC_DIVEU      "eu")
13481                              (UNSPEC_DIVEUO     "euo")])
13483 (define_insn "div<div_extend>_<mode>"
13484   [(set (match_operand:GPR 0 "register_operand" "=r")
13485         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13486                      (match_operand:GPR 2 "register_operand" "r")]
13487                     UNSPEC_DIV_EXTEND))]
13488   "TARGET_POPCNTD"
13489   "div<wd><div_extend> %0,%1,%2"
13490   [(set_attr "type" "div")
13491    (set_attr "size" "<bits>")])
13494 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13496 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13497 (define_mode_attr FP128_64 [(TF "DF")
13498                             (IF "DF")
13499                             (TD "DI")
13500                             (KF "DI")])
13502 (define_expand "unpack<mode>"
13503   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13504         (unspec:<FP128_64>
13505          [(match_operand:FMOVE128 1 "register_operand" "")
13506           (match_operand:QI 2 "const_0_to_1_operand" "")]
13507          UNSPEC_UNPACK_128BIT))]
13508   "FLOAT128_2REG_P (<MODE>mode)"
13509   "")
13511 (define_insn_and_split "unpack<mode>_dm"
13512   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13513         (unspec:<FP128_64>
13514          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13515           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13516          UNSPEC_UNPACK_128BIT))]
13517   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13518   "#"
13519   "&& reload_completed"
13520   [(set (match_dup 0) (match_dup 3))]
13522   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13524   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13525     {
13526       emit_note (NOTE_INSN_DELETED);
13527       DONE;
13528     }
13530   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13532   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13533    (set_attr "length" "4")])
13535 (define_insn_and_split "unpack<mode>_nodm"
13536   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13537         (unspec:<FP128_64>
13538          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13539           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13540          UNSPEC_UNPACK_128BIT))]
13541   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13542   "#"
13543   "&& reload_completed"
13544   [(set (match_dup 0) (match_dup 3))]
13546   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13548   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13549     {
13550       emit_note (NOTE_INSN_DELETED);
13551       DONE;
13552     }
13554   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13556   [(set_attr "type" "fp,fpstore")
13557    (set_attr "length" "4")])
13559 (define_insn_and_split "pack<mode>"
13560   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13561         (unspec:FMOVE128
13562          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13563           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13564          UNSPEC_PACK_128BIT))]
13565   "FLOAT128_2REG_P (<MODE>mode)"
13566   "@
13567    fmr %L0,%2
13568    #"
13569   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13570   [(set (match_dup 3) (match_dup 1))
13571    (set (match_dup 4) (match_dup 2))]
13573   unsigned dest_hi = REGNO (operands[0]);
13574   unsigned dest_lo = dest_hi + 1;
13576   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13577   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13579   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13580   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13582   [(set_attr "type" "fpsimple,fp")
13583    (set_attr "length" "4,8")])
13585 (define_insn "unpack<mode>"
13586   [(set (match_operand:DI 0 "register_operand" "=d,d")
13587         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13588                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13589          UNSPEC_UNPACK_128BIT))]
13590   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13592   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13593     return ASM_COMMENT_START " xxpermdi to same register";
13595   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13596   return "xxpermdi %x0,%x1,%x1,%3";
13598   [(set_attr "type" "vecperm")])
13600 (define_insn "pack<mode>"
13601   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13602         (unspec:FMOVE128_VSX
13603          [(match_operand:DI 1 "register_operand" "d")
13604           (match_operand:DI 2 "register_operand" "d")]
13605          UNSPEC_PACK_128BIT))]
13606   "TARGET_VSX"
13607   "xxpermdi %x0,%x1,%x2,0"
13608   [(set_attr "type" "vecperm")])
13612 ;; ISA 2.08 IEEE 128-bit floating point support.
13614 (define_insn "add<mode>3"
13615   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13616         (plus:IEEE128
13617          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13618          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13619   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13620   "xsaddqp %0,%1,%2"
13621   [(set_attr "type" "vecfloat")
13622    (set_attr "size" "128")])
13624 (define_insn "sub<mode>3"
13625   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13626         (minus:IEEE128
13627          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13628          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13629   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13630   "xssubqp %0,%1,%2"
13631   [(set_attr "type" "vecfloat")
13632    (set_attr "size" "128")])
13634 (define_insn "mul<mode>3"
13635   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13636         (mult:IEEE128
13637          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13638          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13639   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13640   "xsmulqp %0,%1,%2"
13641   [(set_attr "type" "vecfloat")
13642    (set_attr "size" "128")])
13644 (define_insn "div<mode>3"
13645   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13646         (div:IEEE128
13647          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13648          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13649   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13650   "xsdivqp %0,%1,%2"
13651   [(set_attr "type" "vecdiv")
13652    (set_attr "size" "128")])
13654 (define_insn "sqrt<mode>2"
13655   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13656         (sqrt:IEEE128
13657          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13658   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13659    "xssqrtqp %0,%1"
13660   [(set_attr "type" "vecdiv")
13661    (set_attr "size" "128")])
13663 (define_expand "copysign<mode>3"
13664   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13665    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13666    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13667   "FLOAT128_IEEE_P (<MODE>mode)"
13669   if (TARGET_FLOAT128_HW)
13670     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13671                                          operands[2]));
13672   else
13673     {
13674       rtx tmp = gen_reg_rtx (<MODE>mode);
13675       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13676                                            operands[2], tmp));
13677     }
13678   DONE;
13681 (define_insn "copysign<mode>3_hard"
13682   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13683         (unspec:IEEE128
13684          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13685           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13686          UNSPEC_COPYSIGN))]
13687   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13688    "xscpsgnqp %0,%2,%1"
13689   [(set_attr "type" "vecmove")
13690    (set_attr "size" "128")])
13692 (define_insn "copysign<mode>3_soft"
13693   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13694         (unspec:IEEE128
13695          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13696           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13697           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13698          UNSPEC_COPYSIGN))]
13699   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13700    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13701   [(set_attr "type" "veccomplex")
13702    (set_attr "length" "8")])
13704 (define_insn "neg<mode>2_hw"
13705   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13706         (neg:IEEE128
13707          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13708   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13709   "xsnegqp %0,%1"
13710   [(set_attr "type" "vecmove")
13711    (set_attr "size" "128")])
13714 (define_insn "abs<mode>2_hw"
13715   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13716         (abs:IEEE128
13717          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13718   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13719   "xsabsqp %0,%1"
13720   [(set_attr "type" "vecmove")
13721    (set_attr "size" "128")])
13724 (define_insn "*nabs<mode>2_hw"
13725   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13726         (neg:IEEE128
13727          (abs:IEEE128
13728           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13729   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13730   "xsnabsqp %0,%1"
13731   [(set_attr "type" "vecmove")
13732    (set_attr "size" "128")])
13734 ;; Initially don't worry about doing fusion
13735 (define_insn "*fma<mode>4_hw"
13736   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13737         (fma:IEEE128
13738          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13739          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13740          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13741   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13742   "xsmaddqp %0,%1,%2"
13743   [(set_attr "type" "vecfloat")
13744    (set_attr "size" "128")])
13746 (define_insn "*fms<mode>4_hw"
13747   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13748         (fma:IEEE128
13749          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13750          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13751          (neg:IEEE128
13752           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13753   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13754   "xsmsubqp %0,%1,%2"
13755   [(set_attr "type" "vecfloat")
13756    (set_attr "size" "128")])
13758 (define_insn "*nfma<mode>4_hw"
13759   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13760         (neg:IEEE128
13761          (fma:IEEE128
13762           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13763           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13764           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13765   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13766   "xsnmaddqp %0,%1,%2"
13767   [(set_attr "type" "vecfloat")
13768    (set_attr "size" "128")])
13770 (define_insn "*nfms<mode>4_hw"
13771   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13772         (neg:IEEE128
13773          (fma:IEEE128
13774           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13775           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13776           (neg:IEEE128
13777            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13778   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13779   "xsnmsubqp %0,%1,%2"
13780   [(set_attr "type" "vecfloat")
13781    (set_attr "size" "128")])
13783 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13784   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13785         (float_extend:IEEE128
13786          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13787   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13788   "xscvdpqp %0,%1"
13789   [(set_attr "type" "vecfloat")
13790    (set_attr "size" "128")])
13792 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13793 ;; point is a simple copy.
13794 (define_insn_and_split "extendkftf2"
13795   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13796         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13797   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13798   "@
13799    #
13800    xxlor %x0,%x1,%x1"
13801   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13802   [(const_int 0)]
13804   emit_note (NOTE_INSN_DELETED);
13805   DONE;
13807   [(set_attr "type" "*,veclogical")
13808    (set_attr "length" "0,4")])
13810 (define_insn_and_split "trunctfkf2"
13811   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13812         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13813   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13814   "@
13815    #
13816    xxlor %x0,%x1,%x1"
13817   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13818   [(const_int 0)]
13820   emit_note (NOTE_INSN_DELETED);
13821   DONE;
13823   [(set_attr "type" "*,veclogical")
13824    (set_attr "length" "0,4")])
13826 (define_insn "trunc<mode>df2_hw"
13827   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13828         (float_truncate:DF
13829          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13830   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13831   "xscvqpdp %0,%1"
13832   [(set_attr "type" "vecfloat")
13833    (set_attr "size" "128")])
13835 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13836 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13837 ;; conversion
13838 (define_insn_and_split "trunc<mode>sf2_hw"
13839   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13840         (float_truncate:SF
13841          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13842    (clobber (match_scratch:DF 2 "=v"))]
13843   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13844   "#"
13845   "&& 1"
13846   [(set (match_dup 2)
13847         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13848    (set (match_dup 0)
13849         (float_truncate:SF (match_dup 2)))]
13851   if (GET_CODE (operands[2]) == SCRATCH)
13852     operands[2] = gen_reg_rtx (DFmode);
13854   [(set_attr "type" "vecfloat")
13855    (set_attr "length" "8")])
13857 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13858 ;; allowed in the traditional floating point registers. Use V2DImode so that
13859 ;; we can get a value in an Altivec register.
13861 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13862   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13863         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13864    (clobber (match_scratch:V2DI 2 "=v,v"))]
13865   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13866   "#"
13867   "&& 1"
13868   [(pc)]
13870   convert_float128_to_int (operands, <CODE>);
13871   DONE;
13873   [(set_attr "length" "8")
13874    (set_attr "type" "mftgpr,fpstore")])
13876 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13877   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13878         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13879    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13880   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13881   "#"
13882   "&& 1"
13883   [(pc)]
13885   convert_float128_to_int (operands, <CODE>);
13886   DONE;
13888   [(set_attr "length" "8")
13889    (set_attr "type" "mftgpr,vecsimple,fpstore")])
13891 (define_insn_and_split "float<uns>_<mode>si2_hw"
13892   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13893         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13894    (clobber (match_scratch:V2DI 2 "=v,v"))]
13895   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13896   "#"
13897   "&& 1"
13898   [(pc)]
13900   convert_int_to_float128 (operands, <CODE>);
13901   DONE;
13903   [(set_attr "length" "8")
13904    (set_attr "type" "vecfloat")])
13906 (define_insn_and_split "float<uns>_<mode>di2_hw"
13907   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13908         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13909    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13910   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13911   "#"
13912   "&& 1"
13913   [(pc)]
13915   convert_int_to_float128 (operands, <CODE>);
13916   DONE;
13918   [(set_attr "length" "8")
13919    (set_attr "type" "vecfloat")])
13921 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13922 (define_insn "*xscvqp<su>wz_<mode>"
13923   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13924         (unspec:V2DI
13925          [(any_fix:SI
13926            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13927          UNSPEC_IEEE128_CONVERT))]
13928   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13929   "xscvqp<su>wz %0,%1"
13930   [(set_attr "type" "vecfloat")
13931    (set_attr "size" "128")])
13933 (define_insn "*xscvqp<su>dz_<mode>"
13934   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13935         (unspec:V2DI
13936          [(any_fix:DI
13937            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13938          UNSPEC_IEEE128_CONVERT))]
13939   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13940   "xscvqp<su>dz %0,%1"
13941   [(set_attr "type" "vecfloat")
13942    (set_attr "size" "128")])
13944 (define_insn "*xscv<su>dqp_<mode>"
13945   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13946         (any_float:IEEE128
13947          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13948                     UNSPEC_IEEE128_CONVERT)))]
13949   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13950   "xscv<su>dqp %0,%1"
13951   [(set_attr "type" "vecfloat")
13952    (set_attr "size" "128")])
13954 (define_insn "*ieee128_mfvsrd_64bit"
13955   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13956         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13957                    UNSPEC_IEEE128_MOVE))]
13958   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13959   "@
13960    mfvsrd %0,%x1
13961    stxsdx %x1,%y0
13962    xxlor %x0,%x1,%x1"
13963   [(set_attr "type" "mftgpr,fpstore,veclogical")])
13966 (define_insn "*ieee128_mfvsrd_32bit"
13967   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13968         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13969                    UNSPEC_IEEE128_MOVE))]
13970   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13971   "@
13972    stxsdx %x1,%y0
13973    xxlor %x0,%x1,%x1"
13974   [(set_attr "type" "fpstore,veclogical")])
13976 (define_insn "*ieee128_mfvsrwz"
13977   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13978         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13979                    UNSPEC_IEEE128_MOVE))]
13980   "TARGET_FLOAT128_HW"
13981   "@
13982    mfvsrwz %0,%x1
13983    stxsiwx %x1,%y0"
13984   [(set_attr "type" "mftgpr,fpstore")])
13986 ;; 0 says do sign-extension, 1 says zero-extension
13987 (define_insn "*ieee128_mtvsrw"
13988   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13989         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13990                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13991                      UNSPEC_IEEE128_MOVE))]
13992   "TARGET_FLOAT128_HW"
13993   "@
13994    mtvsrwa %x0,%1
13995    lxsiwax %x0,%y1
13996    mtvsrwz %x0,%1
13997    lxsiwzx %x0,%y1"
13998   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
14001 (define_insn "*ieee128_mtvsrd_64bit"
14002   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
14003         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
14004                      UNSPEC_IEEE128_MOVE))]
14005   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14006   "@
14007    mtvsrd %x0,%1
14008    lxsdx %x0,%y1
14009    xxlor %x0,%x1,%x1"
14010   [(set_attr "type" "mffgpr,fpload,veclogical")])
14012 (define_insn "*ieee128_mtvsrd_32bit"
14013   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
14014         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
14015                      UNSPEC_IEEE128_MOVE))]
14016   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14017   "@
14018    lxsdx %x0,%y1
14019    xxlor %x0,%x1,%x1"
14020   [(set_attr "type" "fpload,veclogical")])
14022 ;; IEEE 128-bit instructions with round to odd semantics
14023 (define_insn "*trunc<mode>df2_odd"
14024   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14025         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14026                    UNSPEC_ROUND_TO_ODD))]
14027   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14028   "xscvqpdpo %0,%1"
14029   [(set_attr "type" "vecfloat")
14030    (set_attr "size" "128")])
14032 ;; IEEE 128-bit comparisons
14033 (define_insn "*cmp<mode>_hw"
14034   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14035         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14036                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14037   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14038    "xscmpuqp %0,%1,%2"
14039   [(set_attr "type" "veccmp")
14040    (set_attr "size" "128")])
14044 (include "sync.md")
14045 (include "vector.md")
14046 (include "vsx.md")
14047 (include "altivec.md")
14048 (include "spe.md")
14049 (include "dfp.md")
14050 (include "paired.md")
14051 (include "crypto.md")
14052 (include "htm.md")