* config/rs6000/rs6000.md (cmpmemsi): New define_expand.
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob7b995ac0f259c57c091ac7b3f1a718c1fecbc6b9
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_FLOAT128")
380   (KF "TARGET_FLOAT128")
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 "stxsiwzx %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")
510                                 (IF "TARGET_FLOAT128")
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,??wj,!wz,!wu")
841         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
842   ""
843   "@
844    lwz%U1%X1 %0,%1
845    rldicl %0,%1,0,32
846    mtvsrwz %x0,%1
847    lfiwzx %0,%y1
848    lxsiwzx %x0,%y1"
849   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
851 (define_insn_and_split "*zero_extendsi<mode>2_dot"
852   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
854                     (const_int 0)))
855    (clobber (match_scratch:EXTSI 0 "=r,r"))]
856   "rs6000_gen_cell_microcode"
857   "@
858    rldicl. %0,%1,0,32
859    #"
860   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
861   [(set (match_dup 0)
862         (zero_extend:DI (match_dup 1)))
863    (set (match_dup 2)
864         (compare:CC (match_dup 0)
865                     (const_int 0)))]
866   ""
867   [(set_attr "type" "shift")
868    (set_attr "dot" "yes")
869    (set_attr "length" "4,8")])
871 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
872   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
873         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
874                     (const_int 0)))
875    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
876         (zero_extend:EXTSI (match_dup 1)))]
877   "rs6000_gen_cell_microcode"
878   "@
879    rldicl. %0,%1,0,32
880    #"
881   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
882   [(set (match_dup 0)
883         (zero_extend:EXTSI (match_dup 1)))
884    (set (match_dup 2)
885         (compare:CC (match_dup 0)
886                     (const_int 0)))]
887   ""
888   [(set_attr "type" "shift")
889    (set_attr "dot" "yes")
890    (set_attr "length" "4,8")])
893 (define_insn "extendqi<mode>2"
894   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
895         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
896   ""
897   "extsb %0,%1"
898   [(set_attr "type" "exts")])
900 (define_insn_and_split "*extendqi<mode>2_dot"
901   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
902         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
903                     (const_int 0)))
904    (clobber (match_scratch:EXTQI 0 "=r,r"))]
905   "rs6000_gen_cell_microcode"
906   "@
907    extsb. %0,%1
908    #"
909   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
910   [(set (match_dup 0)
911         (sign_extend:EXTQI (match_dup 1)))
912    (set (match_dup 2)
913         (compare:CC (match_dup 0)
914                     (const_int 0)))]
915   ""
916   [(set_attr "type" "exts")
917    (set_attr "dot" "yes")
918    (set_attr "length" "4,8")])
920 (define_insn_and_split "*extendqi<mode>2_dot2"
921   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
922         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
923                     (const_int 0)))
924    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
925         (sign_extend:EXTQI (match_dup 1)))]
926   "rs6000_gen_cell_microcode"
927   "@
928    extsb. %0,%1
929    #"
930   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
931   [(set (match_dup 0)
932         (sign_extend:EXTQI (match_dup 1)))
933    (set (match_dup 2)
934         (compare:CC (match_dup 0)
935                     (const_int 0)))]
936   ""
937   [(set_attr "type" "exts")
938    (set_attr "dot" "yes")
939    (set_attr "length" "4,8")])
942 (define_expand "extendhi<mode>2"
943   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
944         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
945   ""
946   "")
948 (define_insn "*extendhi<mode>2"
949   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
950         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
951   "rs6000_gen_cell_microcode"
952   "@
953    lha%U1%X1 %0,%1
954    extsh %0,%1"
955   [(set_attr "type" "load,exts")
956    (set_attr "sign_extend" "yes")])
958 (define_insn "*extendhi<mode>2_noload"
959   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
960         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
961   "!rs6000_gen_cell_microcode"
962   "extsh %0,%1"
963   [(set_attr "type" "exts")])
965 (define_insn_and_split "*extendhi<mode>2_dot"
966   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
967         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
968                     (const_int 0)))
969    (clobber (match_scratch:EXTHI 0 "=r,r"))]
970   "rs6000_gen_cell_microcode"
971   "@
972    extsh. %0,%1
973    #"
974   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
975   [(set (match_dup 0)
976         (sign_extend:EXTHI (match_dup 1)))
977    (set (match_dup 2)
978         (compare:CC (match_dup 0)
979                     (const_int 0)))]
980   ""
981   [(set_attr "type" "exts")
982    (set_attr "dot" "yes")
983    (set_attr "length" "4,8")])
985 (define_insn_and_split "*extendhi<mode>2_dot2"
986   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
987         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
988                     (const_int 0)))
989    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
990         (sign_extend:EXTHI (match_dup 1)))]
991   "rs6000_gen_cell_microcode"
992   "@
993    extsh. %0,%1
994    #"
995   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
996   [(set (match_dup 0)
997         (sign_extend:EXTHI (match_dup 1)))
998    (set (match_dup 2)
999         (compare:CC (match_dup 0)
1000                     (const_int 0)))]
1001   ""
1002   [(set_attr "type" "exts")
1003    (set_attr "dot" "yes")
1004    (set_attr "length" "4,8")])
1007 (define_insn "extendsi<mode>2"
1008   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
1009         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
1010   ""
1011   "@
1012    lwa%U1%X1 %0,%1
1013    extsw %0,%1
1014    mtvsrwa %x0,%1
1015    lfiwax %0,%y1
1016    lxsiwax %x0,%y1"
1017   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
1018    (set_attr "sign_extend" "yes")])
1020 (define_insn_and_split "*extendsi<mode>2_dot"
1021   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1022         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1023                     (const_int 0)))
1024    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1025   "rs6000_gen_cell_microcode"
1026   "@
1027    extsw. %0,%1
1028    #"
1029   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1030   [(set (match_dup 0)
1031         (sign_extend:EXTSI (match_dup 1)))
1032    (set (match_dup 2)
1033         (compare:CC (match_dup 0)
1034                     (const_int 0)))]
1035   ""
1036   [(set_attr "type" "exts")
1037    (set_attr "dot" "yes")
1038    (set_attr "length" "4,8")])
1040 (define_insn_and_split "*extendsi<mode>2_dot2"
1041   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1042         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1043                     (const_int 0)))
1044    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1045         (sign_extend:EXTSI (match_dup 1)))]
1046   "rs6000_gen_cell_microcode"
1047   "@
1048    extsw. %0,%1
1049    #"
1050   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1051   [(set (match_dup 0)
1052         (sign_extend:EXTSI (match_dup 1)))
1053    (set (match_dup 2)
1054         (compare:CC (match_dup 0)
1055                     (const_int 0)))]
1056   ""
1057   [(set_attr "type" "exts")
1058    (set_attr "dot" "yes")
1059    (set_attr "length" "4,8")])
1061 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1063 (define_insn "*macchwc"
1064   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1066                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1067                                        (const_int 16))
1068                                       (sign_extend:SI
1069                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1070                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1071                     (const_int 0)))
1072    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1073         (plus:SI (mult:SI (ashiftrt:SI
1074                            (match_dup 2)
1075                            (const_int 16))
1076                           (sign_extend:SI
1077                            (match_dup 1)))
1078                  (match_dup 4)))]
1079   "TARGET_MULHW"
1080   "macchw. %0,%1,%2"
1081   [(set_attr "type" "halfmul")])
1083 (define_insn "*macchw"
1084   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1085         (plus:SI (mult:SI (ashiftrt:SI
1086                            (match_operand:SI 2 "gpc_reg_operand" "r")
1087                            (const_int 16))
1088                           (sign_extend:SI
1089                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1090                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1091   "TARGET_MULHW"
1092   "macchw %0,%1,%2"
1093   [(set_attr "type" "halfmul")])
1095 (define_insn "*macchwuc"
1096   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1097         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1098                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1099                                        (const_int 16))
1100                                       (zero_extend:SI
1101                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1102                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1103                     (const_int 0)))
1104    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1105         (plus:SI (mult:SI (lshiftrt:SI
1106                            (match_dup 2)
1107                            (const_int 16))
1108                           (zero_extend:SI
1109                            (match_dup 1)))
1110                  (match_dup 4)))]
1111   "TARGET_MULHW"
1112   "macchwu. %0,%1,%2"
1113   [(set_attr "type" "halfmul")])
1115 (define_insn "*macchwu"
1116   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1117         (plus:SI (mult:SI (lshiftrt:SI
1118                            (match_operand:SI 2 "gpc_reg_operand" "r")
1119                            (const_int 16))
1120                           (zero_extend:SI
1121                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1122                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1123   "TARGET_MULHW"
1124   "macchwu %0,%1,%2"
1125   [(set_attr "type" "halfmul")])
1127 (define_insn "*machhwc"
1128   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1129         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1130                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1131                                        (const_int 16))
1132                                       (ashiftrt:SI
1133                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1134                                        (const_int 16)))
1135                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1136                     (const_int 0)))
1137    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1138         (plus:SI (mult:SI (ashiftrt:SI
1139                            (match_dup 1)
1140                            (const_int 16))
1141                           (ashiftrt:SI
1142                            (match_dup 2)
1143                            (const_int 16)))
1144                  (match_dup 4)))]
1145   "TARGET_MULHW"
1146   "machhw. %0,%1,%2"
1147   [(set_attr "type" "halfmul")])
1149 (define_insn "*machhw"
1150   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1151         (plus:SI (mult:SI (ashiftrt:SI
1152                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1153                            (const_int 16))
1154                           (ashiftrt:SI
1155                            (match_operand:SI 2 "gpc_reg_operand" "r")
1156                            (const_int 16)))
1157                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1158   "TARGET_MULHW"
1159   "machhw %0,%1,%2"
1160   [(set_attr "type" "halfmul")])
1162 (define_insn "*machhwuc"
1163   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1164         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1165                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1166                                        (const_int 16))
1167                                       (lshiftrt:SI
1168                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1169                                        (const_int 16)))
1170                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1171                     (const_int 0)))
1172    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1173         (plus:SI (mult:SI (lshiftrt:SI
1174                            (match_dup 1)
1175                            (const_int 16))
1176                           (lshiftrt:SI
1177                            (match_dup 2)
1178                            (const_int 16)))
1179                  (match_dup 4)))]
1180   "TARGET_MULHW"
1181   "machhwu. %0,%1,%2"
1182   [(set_attr "type" "halfmul")])
1184 (define_insn "*machhwu"
1185   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186         (plus:SI (mult:SI (lshiftrt:SI
1187                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1188                            (const_int 16))
1189                           (lshiftrt:SI
1190                            (match_operand:SI 2 "gpc_reg_operand" "r")
1191                            (const_int 16)))
1192                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1193   "TARGET_MULHW"
1194   "machhwu %0,%1,%2"
1195   [(set_attr "type" "halfmul")])
1197 (define_insn "*maclhwc"
1198   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1199         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1200                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1201                                       (sign_extend:SI
1202                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1203                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1204                     (const_int 0)))
1205    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1206         (plus:SI (mult:SI (sign_extend:SI
1207                            (match_dup 1))
1208                           (sign_extend:SI
1209                            (match_dup 2)))
1210                  (match_dup 4)))]
1211   "TARGET_MULHW"
1212   "maclhw. %0,%1,%2"
1213   [(set_attr "type" "halfmul")])
1215 (define_insn "*maclhw"
1216   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1217         (plus:SI (mult:SI (sign_extend:SI
1218                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1219                           (sign_extend:SI
1220                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1221                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1222   "TARGET_MULHW"
1223   "maclhw %0,%1,%2"
1224   [(set_attr "type" "halfmul")])
1226 (define_insn "*maclhwuc"
1227   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1229                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1230                                       (zero_extend:SI
1231                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1232                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1233                     (const_int 0)))
1234    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235         (plus:SI (mult:SI (zero_extend:SI
1236                            (match_dup 1))
1237                           (zero_extend:SI
1238                            (match_dup 2)))
1239                  (match_dup 4)))]
1240   "TARGET_MULHW"
1241   "maclhwu. %0,%1,%2"
1242   [(set_attr "type" "halfmul")])
1244 (define_insn "*maclhwu"
1245   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246         (plus:SI (mult:SI (zero_extend:SI
1247                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1248                           (zero_extend:SI
1249                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1250                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1251   "TARGET_MULHW"
1252   "maclhwu %0,%1,%2"
1253   [(set_attr "type" "halfmul")])
1255 (define_insn "*nmacchwc"
1256   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1258                               (mult:SI (ashiftrt:SI
1259                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1260                                         (const_int 16))
1261                                        (sign_extend:SI
1262                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1263                     (const_int 0)))
1264    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265         (minus:SI (match_dup 4)
1266                   (mult:SI (ashiftrt:SI
1267                             (match_dup 2)
1268                             (const_int 16))
1269                            (sign_extend:SI
1270                             (match_dup 1)))))]
1271   "TARGET_MULHW"
1272   "nmacchw. %0,%1,%2"
1273   [(set_attr "type" "halfmul")])
1275 (define_insn "*nmacchw"
1276   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1277         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1278                   (mult:SI (ashiftrt:SI
1279                             (match_operand:SI 2 "gpc_reg_operand" "r")
1280                             (const_int 16))
1281                            (sign_extend:SI
1282                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1283   "TARGET_MULHW"
1284   "nmacchw %0,%1,%2"
1285   [(set_attr "type" "halfmul")])
1287 (define_insn "*nmachhwc"
1288   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1289         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1290                               (mult:SI (ashiftrt:SI
1291                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1292                                         (const_int 16))
1293                                        (ashiftrt:SI
1294                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1295                                         (const_int 16))))
1296                     (const_int 0)))
1297    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1298         (minus:SI (match_dup 4)
1299                   (mult:SI (ashiftrt:SI
1300                             (match_dup 1)
1301                             (const_int 16))
1302                            (ashiftrt:SI
1303                             (match_dup 2)
1304                             (const_int 16)))))]
1305   "TARGET_MULHW"
1306   "nmachhw. %0,%1,%2"
1307   [(set_attr "type" "halfmul")])
1309 (define_insn "*nmachhw"
1310   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1311         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1312                   (mult:SI (ashiftrt:SI
1313                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1314                             (const_int 16))
1315                            (ashiftrt:SI
1316                             (match_operand:SI 2 "gpc_reg_operand" "r")
1317                             (const_int 16)))))]
1318   "TARGET_MULHW"
1319   "nmachhw %0,%1,%2"
1320   [(set_attr "type" "halfmul")])
1322 (define_insn "*nmaclhwc"
1323   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1324         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1325                               (mult:SI (sign_extend:SI
1326                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1327                                        (sign_extend:SI
1328                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1329                     (const_int 0)))
1330    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1331         (minus:SI (match_dup 4)
1332                   (mult:SI (sign_extend:SI
1333                             (match_dup 1))
1334                            (sign_extend:SI
1335                             (match_dup 2)))))]
1336   "TARGET_MULHW"
1337   "nmaclhw. %0,%1,%2"
1338   [(set_attr "type" "halfmul")])
1340 (define_insn "*nmaclhw"
1341   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1342         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1343                   (mult:SI (sign_extend:SI
1344                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1345                            (sign_extend:SI
1346                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1347   "TARGET_MULHW"
1348   "nmaclhw %0,%1,%2"
1349   [(set_attr "type" "halfmul")])
1351 (define_insn "*mulchwc"
1352   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353         (compare:CC (mult:SI (ashiftrt:SI
1354                               (match_operand:SI 2 "gpc_reg_operand" "r")
1355                               (const_int 16))
1356                              (sign_extend:SI
1357                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1358                     (const_int 0)))
1359    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1360         (mult:SI (ashiftrt:SI
1361                   (match_dup 2)
1362                   (const_int 16))
1363                  (sign_extend:SI
1364                   (match_dup 1))))]
1365   "TARGET_MULHW"
1366   "mulchw. %0,%1,%2"
1367   [(set_attr "type" "halfmul")])
1369 (define_insn "*mulchw"
1370   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371         (mult:SI (ashiftrt:SI
1372                   (match_operand:SI 2 "gpc_reg_operand" "r")
1373                   (const_int 16))
1374                  (sign_extend:SI
1375                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1376   "TARGET_MULHW"
1377   "mulchw %0,%1,%2"
1378   [(set_attr "type" "halfmul")])
1380 (define_insn "*mulchwuc"
1381   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1382         (compare:CC (mult:SI (lshiftrt:SI
1383                               (match_operand:SI 2 "gpc_reg_operand" "r")
1384                               (const_int 16))
1385                              (zero_extend:SI
1386                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1387                     (const_int 0)))
1388    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389         (mult:SI (lshiftrt:SI
1390                   (match_dup 2)
1391                   (const_int 16))
1392                  (zero_extend:SI
1393                   (match_dup 1))))]
1394   "TARGET_MULHW"
1395   "mulchwu. %0,%1,%2"
1396   [(set_attr "type" "halfmul")])
1398 (define_insn "*mulchwu"
1399   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400         (mult:SI (lshiftrt:SI
1401                   (match_operand:SI 2 "gpc_reg_operand" "r")
1402                   (const_int 16))
1403                  (zero_extend:SI
1404                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1405   "TARGET_MULHW"
1406   "mulchwu %0,%1,%2"
1407   [(set_attr "type" "halfmul")])
1409 (define_insn "*mulhhwc"
1410   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411         (compare:CC (mult:SI (ashiftrt:SI
1412                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1413                               (const_int 16))
1414                              (ashiftrt:SI
1415                               (match_operand:SI 2 "gpc_reg_operand" "r")
1416                               (const_int 16)))
1417                     (const_int 0)))
1418    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419         (mult:SI (ashiftrt:SI
1420                   (match_dup 1)
1421                   (const_int 16))
1422                  (ashiftrt:SI
1423                   (match_dup 2)
1424                   (const_int 16))))]
1425   "TARGET_MULHW"
1426   "mulhhw. %0,%1,%2"
1427   [(set_attr "type" "halfmul")])
1429 (define_insn "*mulhhw"
1430   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1431         (mult:SI (ashiftrt:SI
1432                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1433                   (const_int 16))
1434                  (ashiftrt:SI
1435                   (match_operand:SI 2 "gpc_reg_operand" "r")
1436                   (const_int 16))))]
1437   "TARGET_MULHW"
1438   "mulhhw %0,%1,%2"
1439   [(set_attr "type" "halfmul")])
1441 (define_insn "*mulhhwuc"
1442   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1443         (compare:CC (mult:SI (lshiftrt:SI
1444                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1445                               (const_int 16))
1446                              (lshiftrt:SI
1447                               (match_operand:SI 2 "gpc_reg_operand" "r")
1448                               (const_int 16)))
1449                     (const_int 0)))
1450    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451         (mult:SI (lshiftrt:SI
1452                   (match_dup 1)
1453                   (const_int 16))
1454                  (lshiftrt:SI
1455                   (match_dup 2)
1456                   (const_int 16))))]
1457   "TARGET_MULHW"
1458   "mulhhwu. %0,%1,%2"
1459   [(set_attr "type" "halfmul")])
1461 (define_insn "*mulhhwu"
1462   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1463         (mult:SI (lshiftrt:SI
1464                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1465                   (const_int 16))
1466                  (lshiftrt:SI
1467                   (match_operand:SI 2 "gpc_reg_operand" "r")
1468                   (const_int 16))))]
1469   "TARGET_MULHW"
1470   "mulhhwu %0,%1,%2"
1471   [(set_attr "type" "halfmul")])
1473 (define_insn "*mullhwc"
1474   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1475         (compare:CC (mult:SI (sign_extend:SI
1476                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1477                              (sign_extend:SI
1478                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1479                     (const_int 0)))
1480    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1481         (mult:SI (sign_extend:SI
1482                   (match_dup 1))
1483                  (sign_extend:SI
1484                   (match_dup 2))))]
1485   "TARGET_MULHW"
1486   "mullhw. %0,%1,%2"
1487   [(set_attr "type" "halfmul")])
1489 (define_insn "*mullhw"
1490   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491         (mult:SI (sign_extend:SI
1492                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1493                  (sign_extend:SI
1494                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1495   "TARGET_MULHW"
1496   "mullhw %0,%1,%2"
1497   [(set_attr "type" "halfmul")])
1499 (define_insn "*mullhwuc"
1500   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1501         (compare:CC (mult:SI (zero_extend:SI
1502                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1503                              (zero_extend:SI
1504                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1505                     (const_int 0)))
1506    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507         (mult:SI (zero_extend:SI
1508                   (match_dup 1))
1509                  (zero_extend:SI
1510                   (match_dup 2))))]
1511   "TARGET_MULHW"
1512   "mullhwu. %0,%1,%2"
1513   [(set_attr "type" "halfmul")])
1515 (define_insn "*mullhwu"
1516   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517         (mult:SI (zero_extend:SI
1518                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1519                  (zero_extend:SI
1520                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1521   "TARGET_MULHW"
1522   "mullhwu %0,%1,%2"
1523   [(set_attr "type" "halfmul")])
1525 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1526 (define_insn "dlmzb"
1527   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1528         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1529                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1530                    UNSPEC_DLMZB_CR))
1531    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532         (unspec:SI [(match_dup 1)
1533                     (match_dup 2)]
1534                    UNSPEC_DLMZB))]
1535   "TARGET_DLMZB"
1536   "dlmzb. %0,%1,%2")
1538 (define_expand "strlensi"
1539   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1540         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1541                     (match_operand:QI 2 "const_int_operand" "")
1542                     (match_operand 3 "const_int_operand" "")]
1543                    UNSPEC_DLMZB_STRLEN))
1544    (clobber (match_scratch:CC 4 "=x"))]
1545   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1547   rtx result = operands[0];
1548   rtx src = operands[1];
1549   rtx search_char = operands[2];
1550   rtx align = operands[3];
1551   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1552   rtx loop_label, end_label, mem, cr0, cond;
1553   if (search_char != const0_rtx
1554       || GET_CODE (align) != CONST_INT
1555       || INTVAL (align) < 8)
1556         FAIL;
1557   word1 = gen_reg_rtx (SImode);
1558   word2 = gen_reg_rtx (SImode);
1559   scratch_dlmzb = gen_reg_rtx (SImode);
1560   scratch_string = gen_reg_rtx (Pmode);
1561   loop_label = gen_label_rtx ();
1562   end_label = gen_label_rtx ();
1563   addr = force_reg (Pmode, XEXP (src, 0));
1564   emit_move_insn (scratch_string, addr);
1565   emit_label (loop_label);
1566   mem = change_address (src, SImode, scratch_string);
1567   emit_move_insn (word1, mem);
1568   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1569   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1570   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1571   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1572   emit_jump_insn (gen_rtx_SET (pc_rtx,
1573                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1574                                                      cond,
1575                                                      gen_rtx_LABEL_REF
1576                                                        (VOIDmode,
1577                                                         end_label),
1578                                                      pc_rtx)));
1579   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1580   emit_jump_insn (gen_rtx_SET (pc_rtx,
1581                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1582   emit_barrier ();
1583   emit_label (end_label);
1584   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1585   emit_insn (gen_subsi3 (result, scratch_string, addr));
1586   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1587   DONE;
1590 ;; Fixed-point arithmetic insns.
1592 (define_expand "add<mode>3"
1593   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1594         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1595                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1596   ""
1598   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1599     {
1600       rtx lo0 = gen_lowpart (SImode, operands[0]);
1601       rtx lo1 = gen_lowpart (SImode, operands[1]);
1602       rtx lo2 = gen_lowpart (SImode, operands[2]);
1603       rtx hi0 = gen_highpart (SImode, operands[0]);
1604       rtx hi1 = gen_highpart (SImode, operands[1]);
1605       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1607       if (!reg_or_short_operand (lo2, SImode))
1608         lo2 = force_reg (SImode, lo2);
1609       if (!adde_operand (hi2, SImode))
1610         hi2 = force_reg (SImode, hi2);
1612       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1613       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1614       DONE;
1615     }
1617   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1618     {
1619       rtx tmp = ((!can_create_pseudo_p ()
1620                   || rtx_equal_p (operands[0], operands[1]))
1621                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1623       HOST_WIDE_INT val = INTVAL (operands[2]);
1624       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1625       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1627       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1628         FAIL;
1630       /* The ordering here is important for the prolog expander.
1631          When space is allocated from the stack, adding 'low' first may
1632          produce a temporary deallocation (which would be bad).  */
1633       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1634       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1635       DONE;
1636     }
1639 (define_insn "*add<mode>3"
1640   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1641         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1642                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1643   ""
1644   "@
1645    add %0,%1,%2
1646    addi %0,%1,%2
1647    addis %0,%1,%v2"
1648   [(set_attr "type" "add")])
1650 (define_insn "addsi3_high"
1651   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1652         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1653                  (high:SI (match_operand 2 "" ""))))]
1654   "TARGET_MACHO && !TARGET_64BIT"
1655   "addis %0,%1,ha16(%2)"
1656   [(set_attr "type" "add")])
1658 (define_insn_and_split "*add<mode>3_dot"
1659   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1660         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1661                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1662                     (const_int 0)))
1663    (clobber (match_scratch:GPR 0 "=r,r"))]
1664   "<MODE>mode == Pmode"
1665   "@
1666    add. %0,%1,%2
1667    #"
1668   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1669   [(set (match_dup 0)
1670         (plus:GPR (match_dup 1)
1671                  (match_dup 2)))
1672    (set (match_dup 3)
1673         (compare:CC (match_dup 0)
1674                     (const_int 0)))]
1675   ""
1676   [(set_attr "type" "add")
1677    (set_attr "dot" "yes")
1678    (set_attr "length" "4,8")])
1680 (define_insn_and_split "*add<mode>3_dot2"
1681   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1682         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1683                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1684                     (const_int 0)))
1685    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1686         (plus:GPR (match_dup 1)
1687                   (match_dup 2)))]
1688   "<MODE>mode == Pmode"
1689   "@
1690    add. %0,%1,%2
1691    #"
1692   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1693   [(set (match_dup 0)
1694         (plus:GPR (match_dup 1)
1695                   (match_dup 2)))
1696    (set (match_dup 3)
1697         (compare:CC (match_dup 0)
1698                     (const_int 0)))]
1699   ""
1700   [(set_attr "type" "add")
1701    (set_attr "dot" "yes")
1702    (set_attr "length" "4,8")])
1704 (define_insn_and_split "*add<mode>3_imm_dot"
1705   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1706         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1707                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1708                     (const_int 0)))
1709    (clobber (match_scratch:GPR 0 "=r,r"))
1710    (clobber (reg:GPR CA_REGNO))]
1711   "<MODE>mode == Pmode"
1712   "@
1713    addic. %0,%1,%2
1714    #"
1715   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1716   [(set (match_dup 0)
1717         (plus:GPR (match_dup 1)
1718                   (match_dup 2)))
1719    (set (match_dup 3)
1720         (compare:CC (match_dup 0)
1721                     (const_int 0)))]
1722   ""
1723   [(set_attr "type" "add")
1724    (set_attr "dot" "yes")
1725    (set_attr "length" "4,8")])
1727 (define_insn_and_split "*add<mode>3_imm_dot2"
1728   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1729         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1730                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1731                     (const_int 0)))
1732    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1733         (plus:GPR (match_dup 1)
1734                   (match_dup 2)))
1735    (clobber (reg:GPR CA_REGNO))]
1736   "<MODE>mode == Pmode"
1737   "@
1738    addic. %0,%1,%2
1739    #"
1740   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1741   [(set (match_dup 0)
1742         (plus:GPR (match_dup 1)
1743                   (match_dup 2)))
1744    (set (match_dup 3)
1745         (compare:CC (match_dup 0)
1746                     (const_int 0)))]
1747   ""
1748   [(set_attr "type" "add")
1749    (set_attr "dot" "yes")
1750    (set_attr "length" "4,8")])
1752 ;; Split an add that we can't do in one insn into two insns, each of which
1753 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1754 ;; add should be last in case the result gets used in an address.
1756 (define_split
1757   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1758         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1759                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1760   ""
1761   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1762    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1764   HOST_WIDE_INT val = INTVAL (operands[2]);
1765   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1766   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1768   operands[4] = GEN_INT (low);
1769   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1770     operands[3] = GEN_INT (rest);
1771   else if (can_create_pseudo_p ())
1772     {
1773       operands[3] = gen_reg_rtx (DImode);
1774       emit_move_insn (operands[3], operands[2]);
1775       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1776       DONE;
1777     }
1778   else
1779     FAIL;
1783 (define_insn "add<mode>3_carry"
1784   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1785         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1786                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1787    (set (reg:P CA_REGNO)
1788         (ltu:P (plus:P (match_dup 1)
1789                        (match_dup 2))
1790                (match_dup 1)))]
1791   ""
1792   "add%I2c %0,%1,%2"
1793   [(set_attr "type" "add")])
1795 (define_insn "*add<mode>3_imm_carry_pos"
1796   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1797         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1798                 (match_operand:P 2 "short_cint_operand" "n")))
1799    (set (reg:P CA_REGNO)
1800         (geu:P (match_dup 1)
1801                (match_operand:P 3 "const_int_operand" "n")))]
1802   "INTVAL (operands[2]) > 0
1803    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1804   "addic %0,%1,%2"
1805   [(set_attr "type" "add")])
1807 (define_insn "*add<mode>3_imm_carry_0"
1808   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1809         (match_operand:P 1 "gpc_reg_operand" "r"))
1810    (set (reg:P CA_REGNO)
1811         (const_int 0))]
1812   ""
1813   "addic %0,%1,0"
1814   [(set_attr "type" "add")])
1816 (define_insn "*add<mode>3_imm_carry_m1"
1817   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1818         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1819                 (const_int -1)))
1820    (set (reg:P CA_REGNO)
1821         (ne:P (match_dup 1)
1822               (const_int 0)))]
1823   ""
1824   "addic %0,%1,-1"
1825   [(set_attr "type" "add")])
1827 (define_insn "*add<mode>3_imm_carry_neg"
1828   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1829         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1830                 (match_operand:P 2 "short_cint_operand" "n")))
1831    (set (reg:P CA_REGNO)
1832         (gtu:P (match_dup 1)
1833                (match_operand:P 3 "const_int_operand" "n")))]
1834   "INTVAL (operands[2]) < 0
1835    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1836   "addic %0,%1,%2"
1837   [(set_attr "type" "add")])
1840 (define_expand "add<mode>3_carry_in"
1841   [(parallel [
1842      (set (match_operand:GPR 0 "gpc_reg_operand")
1843           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1844                               (match_operand:GPR 2 "adde_operand"))
1845                     (reg:GPR CA_REGNO)))
1846      (clobber (reg:GPR CA_REGNO))])]
1847   ""
1849   if (operands[2] == const0_rtx)
1850     {
1851       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1852       DONE;
1853     }
1854   if (operands[2] == constm1_rtx)
1855     {
1856       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1857       DONE;
1858     }
1861 (define_insn "*add<mode>3_carry_in_internal"
1862   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1863         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1864                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1865                   (reg:GPR CA_REGNO)))
1866    (clobber (reg:GPR CA_REGNO))]
1867   ""
1868   "adde %0,%1,%2"
1869   [(set_attr "type" "add")])
1871 (define_insn "add<mode>3_carry_in_0"
1872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1873         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1874                   (reg:GPR CA_REGNO)))
1875    (clobber (reg:GPR CA_REGNO))]
1876   ""
1877   "addze %0,%1"
1878   [(set_attr "type" "add")])
1880 (define_insn "add<mode>3_carry_in_m1"
1881   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1882         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1883                             (reg:GPR CA_REGNO))
1884                   (const_int -1)))
1885    (clobber (reg:GPR CA_REGNO))]
1886   ""
1887   "addme %0,%1"
1888   [(set_attr "type" "add")])
1891 (define_expand "one_cmpl<mode>2"
1892   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1893         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1894   ""
1896   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1897     {
1898       rs6000_split_logical (operands, NOT, false, false, false);
1899       DONE;
1900     }
1903 (define_insn "*one_cmpl<mode>2"
1904   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1906   ""
1907   "not %0,%1")
1909 (define_insn_and_split "*one_cmpl<mode>2_dot"
1910   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1911         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1912                     (const_int 0)))
1913    (clobber (match_scratch:GPR 0 "=r,r"))]
1914   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1915   "@
1916    not. %0,%1
1917    #"
1918   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1919   [(set (match_dup 0)
1920         (not:GPR (match_dup 1)))
1921    (set (match_dup 2)
1922         (compare:CC (match_dup 0)
1923                     (const_int 0)))]
1924   ""
1925   [(set_attr "type" "logical")
1926    (set_attr "dot" "yes")
1927    (set_attr "length" "4,8")])
1929 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1930   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1931         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1932                     (const_int 0)))
1933    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1934         (not:GPR (match_dup 1)))]
1935   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1936   "@
1937    not. %0,%1
1938    #"
1939   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1940   [(set (match_dup 0)
1941         (not:GPR (match_dup 1)))
1942    (set (match_dup 2)
1943         (compare:CC (match_dup 0)
1944                     (const_int 0)))]
1945   ""
1946   [(set_attr "type" "logical")
1947    (set_attr "dot" "yes")
1948    (set_attr "length" "4,8")])
1951 (define_expand "sub<mode>3"
1952   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1953         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1954                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1955   ""
1957   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1958     {
1959       rtx lo0 = gen_lowpart (SImode, operands[0]);
1960       rtx lo1 = gen_lowpart (SImode, operands[1]);
1961       rtx lo2 = gen_lowpart (SImode, operands[2]);
1962       rtx hi0 = gen_highpart (SImode, operands[0]);
1963       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1964       rtx hi2 = gen_highpart (SImode, operands[2]);
1966       if (!reg_or_short_operand (lo1, SImode))
1967         lo1 = force_reg (SImode, lo1);
1968       if (!adde_operand (hi1, SImode))
1969         hi1 = force_reg (SImode, hi1);
1971       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1972       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1973       DONE;
1974     }
1976   if (short_cint_operand (operands[1], <MODE>mode))
1977     {
1978       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1979       DONE;
1980     }
1983 (define_insn "*subf<mode>3"
1984   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1985         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1986                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1987   ""
1988   "subf %0,%1,%2"
1989   [(set_attr "type" "add")])
1991 (define_insn_and_split "*subf<mode>3_dot"
1992   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1993         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1994                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1995                     (const_int 0)))
1996    (clobber (match_scratch:GPR 0 "=r,r"))]
1997   "<MODE>mode == Pmode"
1998   "@
1999    subf. %0,%1,%2
2000    #"
2001   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2002   [(set (match_dup 0)
2003         (minus:GPR (match_dup 2)
2004                    (match_dup 1)))
2005    (set (match_dup 3)
2006         (compare:CC (match_dup 0)
2007                     (const_int 0)))]
2008   ""
2009   [(set_attr "type" "add")
2010    (set_attr "dot" "yes")
2011    (set_attr "length" "4,8")])
2013 (define_insn_and_split "*subf<mode>3_dot2"
2014   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2015         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2016                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2017                     (const_int 0)))
2018    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2019         (minus:GPR (match_dup 2)
2020                    (match_dup 1)))]
2021   "<MODE>mode == Pmode"
2022   "@
2023    subf. %0,%1,%2
2024    #"
2025   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2026   [(set (match_dup 0)
2027         (minus:GPR (match_dup 2)
2028                    (match_dup 1)))
2029    (set (match_dup 3)
2030         (compare:CC (match_dup 0)
2031                     (const_int 0)))]
2032   ""
2033   [(set_attr "type" "add")
2034    (set_attr "dot" "yes")
2035    (set_attr "length" "4,8")])
2037 (define_insn "subf<mode>3_imm"
2038   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2040                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2041    (clobber (reg:GPR CA_REGNO))]
2042   ""
2043   "subfic %0,%1,%2"
2044   [(set_attr "type" "add")])
2047 (define_insn "subf<mode>3_carry"
2048   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2049         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2050                  (match_operand:P 1 "gpc_reg_operand" "r")))
2051    (set (reg:P CA_REGNO)
2052         (leu:P (match_dup 1)
2053                (match_dup 2)))]
2054   ""
2055   "subf%I2c %0,%1,%2"
2056   [(set_attr "type" "add")])
2058 (define_insn "*subf<mode>3_imm_carry_0"
2059   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2060         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2061    (set (reg:P CA_REGNO)
2062         (eq:P (match_dup 1)
2063               (const_int 0)))]
2064   ""
2065   "subfic %0,%1,0"
2066   [(set_attr "type" "add")])
2068 (define_insn "*subf<mode>3_imm_carry_m1"
2069   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2070         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2071    (set (reg:P CA_REGNO)
2072         (const_int 1))]
2073   ""
2074   "subfic %0,%1,-1"
2075   [(set_attr "type" "add")])
2078 (define_expand "subf<mode>3_carry_in"
2079   [(parallel [
2080      (set (match_operand:GPR 0 "gpc_reg_operand")
2081           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2082                               (reg:GPR CA_REGNO))
2083                     (match_operand:GPR 2 "adde_operand")))
2084      (clobber (reg:GPR CA_REGNO))])]
2085   ""
2087   if (operands[2] == const0_rtx)
2088     {
2089       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2090       DONE;
2091     }
2092   if (operands[2] == constm1_rtx)
2093     {
2094       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2095       DONE;
2096     }
2099 (define_insn "*subf<mode>3_carry_in_internal"
2100   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2101         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2102                             (reg:GPR CA_REGNO))
2103                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2104    (clobber (reg:GPR CA_REGNO))]
2105   ""
2106   "subfe %0,%1,%2"
2107   [(set_attr "type" "add")])
2109 (define_insn "subf<mode>3_carry_in_0"
2110   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2111         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2112                   (reg:GPR CA_REGNO)))
2113    (clobber (reg:GPR CA_REGNO))]
2114   ""
2115   "subfze %0,%1"
2116   [(set_attr "type" "add")])
2118 (define_insn "subf<mode>3_carry_in_m1"
2119   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2120         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2121                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2122                   (const_int -2)))
2123    (clobber (reg:GPR CA_REGNO))]
2124   ""
2125   "subfme %0,%1"
2126   [(set_attr "type" "add")])
2128 (define_insn "subf<mode>3_carry_in_xx"
2129   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2130         (plus:GPR (reg:GPR CA_REGNO)
2131                   (const_int -1)))
2132    (clobber (reg:GPR CA_REGNO))]
2133   ""
2134   "subfe %0,%0,%0"
2135   [(set_attr "type" "add")])
2138 (define_insn "neg<mode>2"
2139   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2140         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2141   ""
2142   "neg %0,%1"
2143   [(set_attr "type" "add")])
2145 (define_insn_and_split "*neg<mode>2_dot"
2146   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2147         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2148                     (const_int 0)))
2149    (clobber (match_scratch:GPR 0 "=r,r"))]
2150   "<MODE>mode == Pmode"
2151   "@
2152    neg. %0,%1
2153    #"
2154   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2155   [(set (match_dup 0)
2156         (neg:GPR (match_dup 1)))
2157    (set (match_dup 2)
2158         (compare:CC (match_dup 0)
2159                     (const_int 0)))]
2160   ""
2161   [(set_attr "type" "add")
2162    (set_attr "dot" "yes")
2163    (set_attr "length" "4,8")])
2165 (define_insn_and_split "*neg<mode>2_dot2"
2166   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2167         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2168                     (const_int 0)))
2169    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2170         (neg:GPR (match_dup 1)))]
2171   "<MODE>mode == Pmode"
2172   "@
2173    neg. %0,%1
2174    #"
2175   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2176   [(set (match_dup 0)
2177         (neg:GPR (match_dup 1)))
2178    (set (match_dup 2)
2179         (compare:CC (match_dup 0)
2180                     (const_int 0)))]
2181   ""
2182   [(set_attr "type" "add")
2183    (set_attr "dot" "yes")
2184    (set_attr "length" "4,8")])
2187 (define_insn "clz<mode>2"
2188   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2190   ""
2191   "cntlz<wd> %0,%1"
2192   [(set_attr "type" "cntlz")])
2194 (define_expand "ctz<mode>2"
2195   [(set (match_dup 2)
2196         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2197    (set (match_dup 3)
2198         (and:GPR (match_dup 1)
2199                  (match_dup 2)))
2200    (set (match_dup 4)
2201         (clz:GPR (match_dup 3)))
2202    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2203                    (minus:GPR (match_dup 5)
2204                               (match_dup 4)))
2205               (clobber (reg:GPR CA_REGNO))])]
2206   ""
2208   if (TARGET_CTZ)
2209     {
2210       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2211       DONE;
2212     }
2214   operands[2] = gen_reg_rtx (<MODE>mode);
2215   operands[3] = gen_reg_rtx (<MODE>mode);
2216   operands[4] = gen_reg_rtx (<MODE>mode);
2217   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2220 (define_insn "ctz<mode>2_hw"
2221   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2222         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2223   "TARGET_CTZ"
2224   "cnttz<wd> %0,%1"
2225   [(set_attr "type" "cntlz")])
2227 (define_expand "ffs<mode>2"
2228   [(set (match_dup 2)
2229         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2230    (set (match_dup 3)
2231         (and:GPR (match_dup 1)
2232                  (match_dup 2)))
2233    (set (match_dup 4)
2234         (clz:GPR (match_dup 3)))
2235    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2236                    (minus:GPR (match_dup 5)
2237                               (match_dup 4)))
2238               (clobber (reg:GPR CA_REGNO))])]
2239   ""
2241   operands[2] = gen_reg_rtx (<MODE>mode);
2242   operands[3] = gen_reg_rtx (<MODE>mode);
2243   operands[4] = gen_reg_rtx (<MODE>mode);
2244   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2248 (define_expand "popcount<mode>2"
2249   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2250         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2251   "TARGET_POPCNTB || TARGET_POPCNTD"
2253   rs6000_emit_popcount (operands[0], operands[1]);
2254   DONE;
2257 (define_insn "popcntb<mode>2"
2258   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2259         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2260                     UNSPEC_POPCNTB))]
2261   "TARGET_POPCNTB"
2262   "popcntb %0,%1"
2263   [(set_attr "type" "popcnt")])
2265 (define_insn "popcntd<mode>2"
2266   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2267         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2268   "TARGET_POPCNTD"
2269   "popcnt<wd> %0,%1"
2270   [(set_attr "type" "popcnt")])
2273 (define_expand "parity<mode>2"
2274   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2275         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2276   "TARGET_POPCNTB"
2278   rs6000_emit_parity (operands[0], operands[1]);
2279   DONE;
2282 (define_insn "parity<mode>2_cmpb"
2283   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2284         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2285   "TARGET_CMPB && TARGET_POPCNTB"
2286   "prty<wd> %0,%1"
2287   [(set_attr "type" "popcnt")])
2290 ;; Since the hardware zeros the upper part of the register, save generating the
2291 ;; AND immediate if we are converting to unsigned
2292 (define_insn "*bswaphi2_extenddi"
2293   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2294         (zero_extend:DI
2295          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2296   "TARGET_POWERPC64"
2297   "lhbrx %0,%y1"
2298   [(set_attr "length" "4")
2299    (set_attr "type" "load")])
2301 (define_insn "*bswaphi2_extendsi"
2302   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2303         (zero_extend:SI
2304          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2305   ""
2306   "lhbrx %0,%y1"
2307   [(set_attr "length" "4")
2308    (set_attr "type" "load")])
2310 (define_expand "bswaphi2"
2311   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2312                    (bswap:HI
2313                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2314               (clobber (match_scratch:SI 2 ""))])]
2315   ""
2317   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2318     operands[1] = force_reg (HImode, operands[1]);
2321 (define_insn "bswaphi2_internal"
2322   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2323         (bswap:HI
2324          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2325    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2326   ""
2327   "@
2328    lhbrx %0,%y1
2329    sthbrx %1,%y0
2330    #"
2331   [(set_attr "length" "4,4,12")
2332    (set_attr "type" "load,store,*")])
2334 (define_split
2335   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2336         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2337    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2338   "reload_completed"
2339   [(set (match_dup 3)
2340         (and:SI (lshiftrt:SI (match_dup 4)
2341                              (const_int 8))
2342                 (const_int 255)))
2343    (set (match_dup 2)
2344         (and:SI (ashift:SI (match_dup 4)
2345                            (const_int 8))
2346                 (const_int 65280)))             ;; 0xff00
2347    (set (match_dup 3)
2348         (ior:SI (match_dup 3)
2349                 (match_dup 2)))]
2350   "
2352   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2353   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2356 (define_insn "*bswapsi2_extenddi"
2357   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2358         (zero_extend:DI
2359          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2360   "TARGET_POWERPC64"
2361   "lwbrx %0,%y1"
2362   [(set_attr "length" "4")
2363    (set_attr "type" "load")])
2365 (define_expand "bswapsi2"
2366   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2367         (bswap:SI
2368          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2369   ""
2371   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2372     operands[1] = force_reg (SImode, operands[1]);
2375 (define_insn "*bswapsi2_internal"
2376   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2377         (bswap:SI
2378          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2379   ""
2380   "@
2381    lwbrx %0,%y1
2382    stwbrx %1,%y0
2383    #"
2384   [(set_attr "length" "4,4,12")
2385    (set_attr "type" "load,store,*")])
2387 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2388 ;; zero_extract insns do not change for -mlittle.
2389 (define_split
2390   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2391         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2392   "reload_completed"
2393   [(set (match_dup 0)                                   ; DABC
2394         (rotate:SI (match_dup 1)
2395                    (const_int 24)))
2396    (set (match_dup 0)                                   ; DCBC
2397         (ior:SI (and:SI (ashift:SI (match_dup 1)
2398                                    (const_int 8))
2399                         (const_int 16711680))
2400                 (and:SI (match_dup 0)
2401                         (const_int -16711681))))
2402    (set (match_dup 0)                                   ; DCBA
2403         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2404                                      (const_int 24))
2405                         (const_int 255))
2406                 (and:SI (match_dup 0)
2407                         (const_int -256))))
2409   ]
2410   "")
2412 (define_expand "bswapdi2"
2413   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2414                    (bswap:DI
2415                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2416               (clobber (match_scratch:DI 2 ""))
2417               (clobber (match_scratch:DI 3 ""))])]
2418   ""
2420   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2421     operands[1] = force_reg (DImode, operands[1]);
2423   if (!TARGET_POWERPC64)
2424     {
2425       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2426          that uses 64-bit registers needs the same scratch registers as 64-bit
2427          mode.  */
2428       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2429       DONE;
2430     }
2433 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2434 (define_insn "*bswapdi2_ldbrx"
2435   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2436         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2437    (clobber (match_scratch:DI 2 "=X,X,&r"))
2438    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2439   "TARGET_POWERPC64 && TARGET_LDBRX
2440    && (REG_P (operands[0]) || REG_P (operands[1]))"
2441   "@
2442    ldbrx %0,%y1
2443    stdbrx %1,%y0
2444    #"
2445   [(set_attr "length" "4,4,36")
2446    (set_attr "type" "load,store,*")])
2448 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2449 (define_insn "*bswapdi2_64bit"
2450   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2451         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2452    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2453    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2454   "TARGET_POWERPC64 && !TARGET_LDBRX
2455    && (REG_P (operands[0]) || REG_P (operands[1]))
2456    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2457    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2458   "#"
2459   [(set_attr "length" "16,12,36")])
2461 (define_split
2462   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2463         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2464    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2465    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2466   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2467   [(const_int 0)]
2468   "
2470   rtx dest   = operands[0];
2471   rtx src    = operands[1];
2472   rtx op2    = operands[2];
2473   rtx op3    = operands[3];
2474   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2475                                     BYTES_BIG_ENDIAN ? 4 : 0);
2476   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2477                                      BYTES_BIG_ENDIAN ? 4 : 0);
2478   rtx addr1;
2479   rtx addr2;
2480   rtx word1;
2481   rtx word2;
2483   addr1 = XEXP (src, 0);
2484   if (GET_CODE (addr1) == PLUS)
2485     {
2486       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2487       if (TARGET_AVOID_XFORM)
2488         {
2489           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2490           addr2 = op2;
2491         }
2492       else
2493         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2494     }
2495   else if (TARGET_AVOID_XFORM)
2496     {
2497       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2498       addr2 = op2;
2499     }
2500   else
2501     {
2502       emit_move_insn (op2, GEN_INT (4));
2503       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2504     }
2506   word1 = change_address (src, SImode, addr1);
2507   word2 = change_address (src, SImode, addr2);
2509   if (BYTES_BIG_ENDIAN)
2510     {
2511       emit_insn (gen_bswapsi2 (op3_32, word2));
2512       emit_insn (gen_bswapsi2 (dest_32, word1));
2513     }
2514   else
2515     {
2516       emit_insn (gen_bswapsi2 (op3_32, word1));
2517       emit_insn (gen_bswapsi2 (dest_32, word2));
2518     }
2520   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2521   emit_insn (gen_iordi3 (dest, dest, op3));
2522   DONE;
2525 (define_split
2526   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2527         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2528    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2529    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2530   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2531   [(const_int 0)]
2532   "
2534   rtx dest   = operands[0];
2535   rtx src    = operands[1];
2536   rtx op2    = operands[2];
2537   rtx op3    = operands[3];
2538   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2539                                     BYTES_BIG_ENDIAN ? 4 : 0);
2540   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2541                                     BYTES_BIG_ENDIAN ? 4 : 0);
2542   rtx addr1;
2543   rtx addr2;
2544   rtx word1;
2545   rtx word2;
2547   addr1 = XEXP (dest, 0);
2548   if (GET_CODE (addr1) == PLUS)
2549     {
2550       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2551       if (TARGET_AVOID_XFORM)
2552         {
2553           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2554           addr2 = op2;
2555         }
2556       else
2557         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2558     }
2559   else if (TARGET_AVOID_XFORM)
2560     {
2561       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2562       addr2 = op2;
2563     }
2564   else
2565     {
2566       emit_move_insn (op2, GEN_INT (4));
2567       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2568     }
2570   word1 = change_address (dest, SImode, addr1);
2571   word2 = change_address (dest, SImode, addr2);
2573   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2575   if (BYTES_BIG_ENDIAN)
2576     {
2577       emit_insn (gen_bswapsi2 (word1, src_si));
2578       emit_insn (gen_bswapsi2 (word2, op3_si));
2579     }
2580   else
2581     {
2582       emit_insn (gen_bswapsi2 (word2, src_si));
2583       emit_insn (gen_bswapsi2 (word1, op3_si));
2584     }
2585   DONE;
2588 (define_split
2589   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2590         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2591    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2592    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2593   "TARGET_POWERPC64 && reload_completed"
2594   [(const_int 0)]
2595   "
2597   rtx dest    = operands[0];
2598   rtx src     = operands[1];
2599   rtx op2     = operands[2];
2600   rtx op3     = operands[3];
2601   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2602   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2603   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2604   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2605   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2607   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2608   emit_insn (gen_bswapsi2 (dest_si, src_si));
2609   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2610   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2611   emit_insn (gen_iordi3 (dest, dest, op3));
2612   DONE;
2615 (define_insn "bswapdi2_32bit"
2616   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2617         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2618    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2619   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2620   "#"
2621   [(set_attr "length" "16,12,36")])
2623 (define_split
2624   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2625         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2626    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2627   "!TARGET_POWERPC64 && reload_completed"
2628   [(const_int 0)]
2629   "
2631   rtx dest  = operands[0];
2632   rtx src   = operands[1];
2633   rtx op2   = operands[2];
2634   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2635   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2636   rtx addr1;
2637   rtx addr2;
2638   rtx word1;
2639   rtx word2;
2641   addr1 = XEXP (src, 0);
2642   if (GET_CODE (addr1) == PLUS)
2643     {
2644       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2645       if (TARGET_AVOID_XFORM
2646           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2647         {
2648           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2649           addr2 = op2;
2650         }
2651       else
2652         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2653     }
2654   else if (TARGET_AVOID_XFORM
2655            || REGNO (addr1) == REGNO (dest2))
2656     {
2657       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2658       addr2 = op2;
2659     }
2660   else
2661     {
2662       emit_move_insn (op2, GEN_INT (4));
2663       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2664     }
2666   word1 = change_address (src, SImode, addr1);
2667   word2 = change_address (src, SImode, addr2);
2669   emit_insn (gen_bswapsi2 (dest2, word1));
2670   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2671      thus allowing us to omit an early clobber on the output.  */
2672   emit_insn (gen_bswapsi2 (dest1, word2));
2673   DONE;
2676 (define_split
2677   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2678         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2679    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2680   "!TARGET_POWERPC64 && reload_completed"
2681   [(const_int 0)]
2682   "
2684   rtx dest = operands[0];
2685   rtx src  = operands[1];
2686   rtx op2  = operands[2];
2687   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2688   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2689   rtx addr1;
2690   rtx addr2;
2691   rtx word1;
2692   rtx word2;
2694   addr1 = XEXP (dest, 0);
2695   if (GET_CODE (addr1) == PLUS)
2696     {
2697       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2698       if (TARGET_AVOID_XFORM)
2699         {
2700           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2701           addr2 = op2;
2702         }
2703       else
2704         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2705     }
2706   else if (TARGET_AVOID_XFORM)
2707     {
2708       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2709       addr2 = op2;
2710     }
2711   else
2712     {
2713       emit_move_insn (op2, GEN_INT (4));
2714       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2715     }
2717   word1 = change_address (dest, SImode, addr1);
2718   word2 = change_address (dest, SImode, addr2);
2720   emit_insn (gen_bswapsi2 (word2, src1));
2721   emit_insn (gen_bswapsi2 (word1, src2));
2722   DONE;
2725 (define_split
2726   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2727         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2728    (clobber (match_operand:SI 2 "" ""))]
2729   "!TARGET_POWERPC64 && reload_completed"
2730   [(const_int 0)]
2731   "
2733   rtx dest  = operands[0];
2734   rtx src   = operands[1];
2735   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2736   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2737   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2738   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2740   emit_insn (gen_bswapsi2 (dest1, src2));
2741   emit_insn (gen_bswapsi2 (dest2, src1));
2742   DONE;
2746 (define_insn "mul<mode>3"
2747   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2748         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2749                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2750   ""
2751   "@
2752    mull<wd> %0,%1,%2
2753    mulli %0,%1,%2"
2754    [(set_attr "type" "mul")
2755     (set (attr "size")
2756       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2757                 (const_string "8")
2758              (match_operand:GPR 2 "short_cint_operand" "")
2759                 (const_string "16")]
2760         (const_string "<bits>")))])
2762 (define_insn_and_split "*mul<mode>3_dot"
2763   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2764         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2765                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2766                     (const_int 0)))
2767    (clobber (match_scratch:GPR 0 "=r,r"))]
2768   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2769   "@
2770    mull<wd>. %0,%1,%2
2771    #"
2772   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2773   [(set (match_dup 0)
2774         (mult:GPR (match_dup 1)
2775                   (match_dup 2)))
2776    (set (match_dup 3)
2777         (compare:CC (match_dup 0)
2778                     (const_int 0)))]
2779   ""
2780   [(set_attr "type" "mul")
2781    (set_attr "size" "<bits>")
2782    (set_attr "dot" "yes")
2783    (set_attr "length" "4,8")])
2785 (define_insn_and_split "*mul<mode>3_dot2"
2786   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2787         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2788                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2789                     (const_int 0)))
2790    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2791         (mult:GPR (match_dup 1)
2792                   (match_dup 2)))]
2793   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2794   "@
2795    mull<wd>. %0,%1,%2
2796    #"
2797   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2798   [(set (match_dup 0)
2799         (mult:GPR (match_dup 1)
2800                   (match_dup 2)))
2801    (set (match_dup 3)
2802         (compare:CC (match_dup 0)
2803                     (const_int 0)))]
2804   ""
2805   [(set_attr "type" "mul")
2806    (set_attr "size" "<bits>")
2807    (set_attr "dot" "yes")
2808    (set_attr "length" "4,8")])
2811 (define_expand "<su>mul<mode>3_highpart"
2812   [(set (match_operand:GPR 0 "gpc_reg_operand")
2813         (subreg:GPR
2814           (mult:<DMODE> (any_extend:<DMODE>
2815                           (match_operand:GPR 1 "gpc_reg_operand"))
2816                         (any_extend:<DMODE>
2817                           (match_operand:GPR 2 "gpc_reg_operand")))
2818          0))]
2819   ""
2821   if (<MODE>mode == SImode && TARGET_POWERPC64)
2822     {
2823       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2824                                              operands[2]));
2825       DONE;
2826     }
2828   if (!WORDS_BIG_ENDIAN)
2829     {
2830       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2831                                                  operands[2]));
2832       DONE;
2833     }
2836 (define_insn "*<su>mul<mode>3_highpart"
2837   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2838         (subreg:GPR
2839           (mult:<DMODE> (any_extend:<DMODE>
2840                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2841                         (any_extend:<DMODE>
2842                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2843          0))]
2844   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2845   "mulh<wd><u> %0,%1,%2"
2846   [(set_attr "type" "mul")
2847    (set_attr "size" "<bits>")])
2849 (define_insn "<su>mulsi3_highpart_le"
2850   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2851         (subreg:SI
2852           (mult:DI (any_extend:DI
2853                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2854                    (any_extend:DI
2855                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2856          4))]
2857   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2858   "mulhw<u> %0,%1,%2"
2859   [(set_attr "type" "mul")])
2861 (define_insn "<su>muldi3_highpart_le"
2862   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2863         (subreg:DI
2864           (mult:TI (any_extend:TI
2865                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2866                    (any_extend:TI
2867                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2868          8))]
2869   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2870   "mulhd<u> %0,%1,%2"
2871   [(set_attr "type" "mul")
2872    (set_attr "size" "64")])
2874 (define_insn "<su>mulsi3_highpart_64"
2875   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2876         (truncate:SI
2877           (lshiftrt:DI
2878             (mult:DI (any_extend:DI
2879                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2880                      (any_extend:DI
2881                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2882             (const_int 32))))]
2883   "TARGET_POWERPC64"
2884   "mulhw<u> %0,%1,%2"
2885   [(set_attr "type" "mul")])
2887 (define_expand "<u>mul<mode><dmode>3"
2888   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2889         (mult:<DMODE> (any_extend:<DMODE>
2890                         (match_operand:GPR 1 "gpc_reg_operand"))
2891                       (any_extend:<DMODE>
2892                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2893   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2895   rtx l = gen_reg_rtx (<MODE>mode);
2896   rtx h = gen_reg_rtx (<MODE>mode);
2897   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2898   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2899   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2900   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2901   DONE;
2904 (define_insn "*maddld4"
2905   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2906         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2907                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2908                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2909   "TARGET_MADDLD"
2910   "maddld %0,%1,%2,%3"
2911   [(set_attr "type" "mul")])
2913 (define_insn "udiv<mode>3"
2914   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2915         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2916                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2917   ""
2918   "div<wd>u %0,%1,%2"
2919   [(set_attr "type" "div")
2920    (set_attr "size" "<bits>")])
2923 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2924 ;; modulus.  If it isn't a power of two, force operands into register and do
2925 ;; a normal divide.
2926 (define_expand "div<mode>3"
2927   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2928         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2929                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2930   ""
2932   if (CONST_INT_P (operands[2])
2933       && INTVAL (operands[2]) > 0
2934       && exact_log2 (INTVAL (operands[2])) >= 0)
2935     {
2936       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2937       DONE;
2938     }
2940   operands[2] = force_reg (<MODE>mode, operands[2]);
2943 (define_insn "*div<mode>3"
2944   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2945         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2946                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2947   ""
2948   "div<wd> %0,%1,%2"
2949   [(set_attr "type" "div")
2950    (set_attr "size" "<bits>")])
2952 (define_insn "div<mode>3_sra"
2953   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2954         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2955                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2956    (clobber (reg:GPR CA_REGNO))]
2957   ""
2958   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2959   [(set_attr "type" "two")
2960    (set_attr "length" "8")])
2962 (define_insn_and_split "*div<mode>3_sra_dot"
2963   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2964         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2965                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2966                     (const_int 0)))
2967    (clobber (match_scratch:GPR 0 "=r,r"))
2968    (clobber (reg:GPR CA_REGNO))]
2969   "<MODE>mode == Pmode"
2970   "@
2971    sra<wd>i %0,%1,%p2\;addze. %0,%0
2972    #"
2973   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2974   [(parallel [(set (match_dup 0)
2975                    (div:GPR (match_dup 1)
2976                             (match_dup 2)))
2977               (clobber (reg:GPR CA_REGNO))])
2978    (set (match_dup 3)
2979         (compare:CC (match_dup 0)
2980                     (const_int 0)))]
2981   ""
2982   [(set_attr "type" "two")
2983    (set_attr "length" "8,12")
2984    (set_attr "cell_micro" "not")])
2986 (define_insn_and_split "*div<mode>3_sra_dot2"
2987   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2988         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2989                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2990                     (const_int 0)))
2991    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2992         (div:GPR (match_dup 1)
2993                  (match_dup 2)))
2994    (clobber (reg:GPR CA_REGNO))]
2995   "<MODE>mode == Pmode"
2996   "@
2997    sra<wd>i %0,%1,%p2\;addze. %0,%0
2998    #"
2999   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3000   [(parallel [(set (match_dup 0)
3001                    (div:GPR (match_dup 1)
3002                             (match_dup 2)))
3003               (clobber (reg:GPR CA_REGNO))])
3004    (set (match_dup 3)
3005         (compare:CC (match_dup 0)
3006                     (const_int 0)))]
3007   ""
3008   [(set_attr "type" "two")
3009    (set_attr "length" "8,12")
3010    (set_attr "cell_micro" "not")])
3012 (define_expand "mod<mode>3"
3013   [(set (match_operand:GPR 0 "gpc_reg_operand")
3014         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3015                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3016   ""
3018   int i;
3019   rtx temp1;
3020   rtx temp2;
3022   if (GET_CODE (operands[2]) != CONST_INT
3023       || INTVAL (operands[2]) <= 0
3024       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3025     {
3026       if (!TARGET_MODULO)
3027         FAIL;
3029       operands[2] = force_reg (<MODE>mode, operands[2]);
3030     }
3031   else
3032     {
3033       temp1 = gen_reg_rtx (<MODE>mode);
3034       temp2 = gen_reg_rtx (<MODE>mode);
3036       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3037       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3038       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3039       DONE;
3040     }
3043 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3044 ;; mod, prefer putting the result of mod into a different register
3045 (define_insn "*mod<mode>3"
3046   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3047         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3048                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3049   "TARGET_MODULO"
3050   "mods<wd> %0,%1,%2"
3051   [(set_attr "type" "div")
3052    (set_attr "size" "<bits>")])
3055 (define_insn "umod<mode>3"
3056   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3057         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3058                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3059   "TARGET_MODULO"
3060   "modu<wd> %0,%1,%2"
3061   [(set_attr "type" "div")
3062    (set_attr "size" "<bits>")])
3064 ;; On machines with modulo support, do a combined div/mod the old fashioned
3065 ;; method, since the multiply/subtract is faster than doing the mod instruction
3066 ;; after a divide.
3068 (define_peephole2
3069   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3070         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3071                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3072    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3073         (mod:GPR (match_dup 1)
3074                  (match_dup 2)))]
3075   "TARGET_MODULO
3076    && ! reg_mentioned_p (operands[0], operands[1])
3077    && ! reg_mentioned_p (operands[0], operands[2])
3078    && ! reg_mentioned_p (operands[3], operands[1])
3079    && ! reg_mentioned_p (operands[3], operands[2])"
3080   [(set (match_dup 0)
3081         (div:GPR (match_dup 1)
3082                  (match_dup 2)))
3083    (set (match_dup 3)
3084         (mult:GPR (match_dup 0)
3085                   (match_dup 2)))
3086    (set (match_dup 3)
3087         (minus:GPR (match_dup 1)
3088                    (match_dup 3)))])
3090 (define_peephole2
3091   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3092         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3093                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3094    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3095         (umod:GPR (match_dup 1)
3096                   (match_dup 2)))]
3097   "TARGET_MODULO
3098    && ! reg_mentioned_p (operands[0], operands[1])
3099    && ! reg_mentioned_p (operands[0], operands[2])
3100    && ! reg_mentioned_p (operands[3], operands[1])
3101    && ! reg_mentioned_p (operands[3], operands[2])"
3102   [(set (match_dup 0)
3103         (div:GPR (match_dup 1)
3104                  (match_dup 2)))
3105    (set (match_dup 3)
3106         (mult:GPR (match_dup 0)
3107                   (match_dup 2)))
3108    (set (match_dup 3)
3109         (minus:GPR (match_dup 1)
3110                    (match_dup 3)))])
3113 ;; Logical instructions
3114 ;; The logical instructions are mostly combined by using match_operator,
3115 ;; but the plain AND insns are somewhat different because there is no
3116 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3117 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3119 (define_expand "and<mode>3"
3120   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3121         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3122                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3123   ""
3125   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3126     {
3127       rs6000_split_logical (operands, AND, false, false, false);
3128       DONE;
3129     }
3131   if (CONST_INT_P (operands[2]))
3132     {
3133       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3134         {
3135           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3136           DONE;
3137         }
3139       if (logical_const_operand (operands[2], <MODE>mode)
3140           && rs6000_gen_cell_microcode)
3141         {
3142           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3143           DONE;
3144         }
3146       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3147         {
3148           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3149           DONE;
3150         }
3152       operands[2] = force_reg (<MODE>mode, operands[2]);
3153     }
3157 (define_insn "and<mode>3_imm"
3158   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3159         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3160                  (match_operand:GPR 2 "logical_const_operand" "n")))
3161    (clobber (match_scratch:CC 3 "=x"))]
3162   "rs6000_gen_cell_microcode
3163    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3164   "andi%e2. %0,%1,%u2"
3165   [(set_attr "type" "logical")
3166    (set_attr "dot" "yes")])
3168 (define_insn_and_split "*and<mode>3_imm_dot"
3169   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3170         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3171                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3172                     (const_int 0)))
3173    (clobber (match_scratch:GPR 0 "=r,r"))
3174    (clobber (match_scratch:CC 4 "=X,x"))]
3175   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3176    && rs6000_gen_cell_microcode
3177    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3178   "@
3179    andi%e2. %0,%1,%u2
3180    #"
3181   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3182   [(parallel [(set (match_dup 0)
3183                    (and:GPR (match_dup 1)
3184                             (match_dup 2)))
3185               (clobber (match_dup 4))])
3186    (set (match_dup 3)
3187         (compare:CC (match_dup 0)
3188                     (const_int 0)))]
3189   ""
3190   [(set_attr "type" "logical")
3191    (set_attr "dot" "yes")
3192    (set_attr "length" "4,8")])
3194 (define_insn_and_split "*and<mode>3_imm_dot2"
3195   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3196         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3197                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3198                     (const_int 0)))
3199    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3200         (and:GPR (match_dup 1)
3201                  (match_dup 2)))
3202    (clobber (match_scratch:CC 4 "=X,x"))]
3203   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3204    && rs6000_gen_cell_microcode
3205    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3206   "@
3207    andi%e2. %0,%1,%u2
3208    #"
3209   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210   [(parallel [(set (match_dup 0)
3211                    (and:GPR (match_dup 1)
3212                             (match_dup 2)))
3213               (clobber (match_dup 4))])
3214    (set (match_dup 3)
3215         (compare:CC (match_dup 0)
3216                     (const_int 0)))]
3217   ""
3218   [(set_attr "type" "logical")
3219    (set_attr "dot" "yes")
3220    (set_attr "length" "4,8")])
3222 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3223   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3224         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3225                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3226                     (const_int 0)))
3227    (clobber (match_scratch:GPR 0 "=r,r"))]
3228   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3229    && rs6000_gen_cell_microcode"
3230   "@
3231    andi%e2. %0,%1,%u2
3232    #"
3233   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3234   [(set (match_dup 0)
3235         (and:GPR (match_dup 1)
3236                  (match_dup 2)))
3237    (set (match_dup 3)
3238         (compare:CC (match_dup 0)
3239                     (const_int 0)))]
3240   ""
3241   [(set_attr "type" "logical")
3242    (set_attr "dot" "yes")
3243    (set_attr "length" "4,8")])
3245 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3246   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3247         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3248                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3249                     (const_int 0)))
3250    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3251         (and:GPR (match_dup 1)
3252                  (match_dup 2)))]
3253   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3254    && rs6000_gen_cell_microcode"
3255   "@
3256    andi%e2. %0,%1,%u2
3257    #"
3258   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3259   [(set (match_dup 0)
3260         (and:GPR (match_dup 1)
3261                  (match_dup 2)))
3262    (set (match_dup 3)
3263         (compare:CC (match_dup 0)
3264                     (const_int 0)))]
3265   ""
3266   [(set_attr "type" "logical")
3267    (set_attr "dot" "yes")
3268    (set_attr "length" "4,8")])
3270 (define_insn "*and<mode>3_imm_dot_shifted"
3271   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3272         (compare:CC
3273           (and:GPR
3274             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3275                           (match_operand:SI 4 "const_int_operand" "n"))
3276             (match_operand:GPR 2 "const_int_operand" "n"))
3277           (const_int 0)))
3278    (clobber (match_scratch:GPR 0 "=r"))]
3279   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3280                                    << INTVAL (operands[4])),
3281                           DImode)
3282    && (<MODE>mode == Pmode
3283        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3284    && rs6000_gen_cell_microcode"
3286   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3287   return "andi%e2. %0,%1,%u2";
3289   [(set_attr "type" "logical")
3290    (set_attr "dot" "yes")])
3293 (define_insn "and<mode>3_mask"
3294   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3295         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3296                  (match_operand:GPR 2 "const_int_operand" "n")))]
3297   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3299   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3301   [(set_attr "type" "shift")])
3303 (define_insn_and_split "*and<mode>3_mask_dot"
3304   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3305         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3306                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3307                     (const_int 0)))
3308    (clobber (match_scratch:GPR 0 "=r,r"))]
3309   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3310    && rs6000_gen_cell_microcode
3311    && !logical_const_operand (operands[2], <MODE>mode)
3312    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3314   if (which_alternative == 0)
3315     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3316   else
3317     return "#";
3319   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3320   [(set (match_dup 0)
3321         (and:GPR (match_dup 1)
3322                  (match_dup 2)))
3323    (set (match_dup 3)
3324         (compare:CC (match_dup 0)
3325                     (const_int 0)))]
3326   ""
3327   [(set_attr "type" "shift")
3328    (set_attr "dot" "yes")
3329    (set_attr "length" "4,8")])
3331 (define_insn_and_split "*and<mode>3_mask_dot2"
3332   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3333         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3335                     (const_int 0)))
3336    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3337         (and:GPR (match_dup 1)
3338                  (match_dup 2)))]
3339   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3340    && rs6000_gen_cell_microcode
3341    && !logical_const_operand (operands[2], <MODE>mode)
3342    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3344   if (which_alternative == 0)
3345     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3346   else
3347     return "#";
3349   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3350   [(set (match_dup 0)
3351         (and:GPR (match_dup 1)
3352                  (match_dup 2)))
3353    (set (match_dup 3)
3354         (compare:CC (match_dup 0)
3355                     (const_int 0)))]
3356   ""
3357   [(set_attr "type" "shift")
3358    (set_attr "dot" "yes")
3359    (set_attr "length" "4,8")])
3362 (define_insn_and_split "*and<mode>3_2insn"
3363   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3364         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3365                  (match_operand:GPR 2 "const_int_operand" "n")))]
3366   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3367    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3368         || (logical_const_operand (operands[2], <MODE>mode)
3369             && rs6000_gen_cell_microcode))"
3370   "#"
3371   "&& 1"
3372   [(pc)]
3374   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3375   DONE;
3377   [(set_attr "type" "shift")
3378    (set_attr "length" "8")])
3380 (define_insn_and_split "*and<mode>3_2insn_dot"
3381   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3382         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3383                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3384                     (const_int 0)))
3385    (clobber (match_scratch:GPR 0 "=r,r"))]
3386   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3387    && rs6000_gen_cell_microcode
3388    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3389    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3390         || (logical_const_operand (operands[2], <MODE>mode)
3391             && rs6000_gen_cell_microcode))"
3392   "#"
3393   "&& reload_completed"
3394   [(pc)]
3396   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3397   DONE;
3399   [(set_attr "type" "shift")
3400    (set_attr "dot" "yes")
3401    (set_attr "length" "8,12")])
3403 (define_insn_and_split "*and<mode>3_2insn_dot2"
3404   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3405         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3406                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3407                     (const_int 0)))
3408    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3409         (and:GPR (match_dup 1)
3410                  (match_dup 2)))]
3411   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3412    && rs6000_gen_cell_microcode
3413    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3414    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3415         || (logical_const_operand (operands[2], <MODE>mode)
3416             && rs6000_gen_cell_microcode))"
3417   "#"
3418   "&& reload_completed"
3419   [(pc)]
3421   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3422   DONE;
3424   [(set_attr "type" "shift")
3425    (set_attr "dot" "yes")
3426    (set_attr "length" "8,12")])
3429 (define_expand "<code><mode>3"
3430   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3431         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3432                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3433   ""
3435   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3436     {
3437       rs6000_split_logical (operands, <CODE>, false, false, false);
3438       DONE;
3439     }
3441   if (non_logical_cint_operand (operands[2], <MODE>mode))
3442     {
3443       rtx tmp = ((!can_create_pseudo_p ()
3444                   || rtx_equal_p (operands[0], operands[1]))
3445                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3447       HOST_WIDE_INT value = INTVAL (operands[2]);
3448       HOST_WIDE_INT lo = value & 0xffff;
3449       HOST_WIDE_INT hi = value - lo;
3451       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3452       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3453       DONE;
3454     }
3456   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3457     operands[2] = force_reg (<MODE>mode, operands[2]);
3460 (define_split
3461   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3462         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3463                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3464   ""
3465   [(set (match_dup 3)
3466         (iorxor:GPR (match_dup 1)
3467                     (match_dup 4)))
3468    (set (match_dup 0)
3469         (iorxor:GPR (match_dup 3)
3470                     (match_dup 5)))]
3472   operands[3] = ((!can_create_pseudo_p ()
3473                   || rtx_equal_p (operands[0], operands[1]))
3474                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3476   HOST_WIDE_INT value = INTVAL (operands[2]);
3477   HOST_WIDE_INT lo = value & 0xffff;
3478   HOST_WIDE_INT hi = value - lo;
3480   operands[4] = GEN_INT (hi);
3481   operands[5] = GEN_INT (lo);
3484 (define_insn "*bool<mode>3_imm"
3485   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3486         (match_operator:GPR 3 "boolean_or_operator"
3487          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3488           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3489   ""
3490   "%q3i%e2 %0,%1,%u2"
3491   [(set_attr "type" "logical")])
3493 (define_insn "*bool<mode>3"
3494   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3495         (match_operator:GPR 3 "boolean_operator"
3496          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3497           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3498   ""
3499   "%q3 %0,%1,%2"
3500   [(set_attr "type" "logical")])
3502 (define_insn_and_split "*bool<mode>3_dot"
3503   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3504         (compare:CC (match_operator:GPR 3 "boolean_operator"
3505          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3506           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3507          (const_int 0)))
3508    (clobber (match_scratch:GPR 0 "=r,r"))]
3509   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3510   "@
3511    %q3. %0,%1,%2
3512    #"
3513   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3514   [(set (match_dup 0)
3515         (match_dup 3))
3516    (set (match_dup 4)
3517         (compare:CC (match_dup 0)
3518                     (const_int 0)))]
3519   ""
3520   [(set_attr "type" "logical")
3521    (set_attr "dot" "yes")
3522    (set_attr "length" "4,8")])
3524 (define_insn_and_split "*bool<mode>3_dot2"
3525   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3526         (compare:CC (match_operator:GPR 3 "boolean_operator"
3527          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3528           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3529          (const_int 0)))
3530    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3531         (match_dup 3))]
3532   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3533   "@
3534    %q3. %0,%1,%2
3535    #"
3536   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3537   [(set (match_dup 0)
3538         (match_dup 3))
3539    (set (match_dup 4)
3540         (compare:CC (match_dup 0)
3541                     (const_int 0)))]
3542   ""
3543   [(set_attr "type" "logical")
3544    (set_attr "dot" "yes")
3545    (set_attr "length" "4,8")])
3548 (define_insn "*boolc<mode>3"
3549   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3550         (match_operator:GPR 3 "boolean_operator"
3551          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3552           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3553   ""
3554   "%q3 %0,%1,%2"
3555   [(set_attr "type" "logical")])
3557 (define_insn_and_split "*boolc<mode>3_dot"
3558   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3559         (compare:CC (match_operator:GPR 3 "boolean_operator"
3560          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3561           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3562          (const_int 0)))
3563    (clobber (match_scratch:GPR 0 "=r,r"))]
3564   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3565   "@
3566    %q3. %0,%1,%2
3567    #"
3568   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3569   [(set (match_dup 0)
3570         (match_dup 3))
3571    (set (match_dup 4)
3572         (compare:CC (match_dup 0)
3573                     (const_int 0)))]
3574   ""
3575   [(set_attr "type" "logical")
3576    (set_attr "dot" "yes")
3577    (set_attr "length" "4,8")])
3579 (define_insn_and_split "*boolc<mode>3_dot2"
3580   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3581         (compare:CC (match_operator:GPR 3 "boolean_operator"
3582          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3583           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3584          (const_int 0)))
3585    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3586         (match_dup 3))]
3587   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3588   "@
3589    %q3. %0,%1,%2
3590    #"
3591   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3592   [(set (match_dup 0)
3593         (match_dup 3))
3594    (set (match_dup 4)
3595         (compare:CC (match_dup 0)
3596                     (const_int 0)))]
3597   ""
3598   [(set_attr "type" "logical")
3599    (set_attr "dot" "yes")
3600    (set_attr "length" "4,8")])
3603 (define_insn "*boolcc<mode>3"
3604   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3605         (match_operator:GPR 3 "boolean_operator"
3606          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3607           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3608   ""
3609   "%q3 %0,%1,%2"
3610   [(set_attr "type" "logical")])
3612 (define_insn_and_split "*boolcc<mode>3_dot"
3613   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3614         (compare:CC (match_operator:GPR 3 "boolean_operator"
3615          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3616           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3617          (const_int 0)))
3618    (clobber (match_scratch:GPR 0 "=r,r"))]
3619   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3620   "@
3621    %q3. %0,%1,%2
3622    #"
3623   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3624   [(set (match_dup 0)
3625         (match_dup 3))
3626    (set (match_dup 4)
3627         (compare:CC (match_dup 0)
3628                     (const_int 0)))]
3629   ""
3630   [(set_attr "type" "logical")
3631    (set_attr "dot" "yes")
3632    (set_attr "length" "4,8")])
3634 (define_insn_and_split "*boolcc<mode>3_dot2"
3635   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3636         (compare:CC (match_operator:GPR 3 "boolean_operator"
3637          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3638           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3639          (const_int 0)))
3640    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3641         (match_dup 3))]
3642   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3643   "@
3644    %q3. %0,%1,%2
3645    #"
3646   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3647   [(set (match_dup 0)
3648         (match_dup 3))
3649    (set (match_dup 4)
3650         (compare:CC (match_dup 0)
3651                     (const_int 0)))]
3652   ""
3653   [(set_attr "type" "logical")
3654    (set_attr "dot" "yes")
3655    (set_attr "length" "4,8")])
3658 ;; TODO: Should have dots of this as well.
3659 (define_insn "*eqv<mode>3"
3660   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3661         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3662                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3663   ""
3664   "eqv %0,%1,%2"
3665   [(set_attr "type" "logical")])
3667 ;; Rotate-and-mask and insert.
3669 (define_insn "*rotl<mode>3_mask"
3670   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3671         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3672                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3673                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3674                  (match_operand:GPR 3 "const_int_operand" "n")))]
3675   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3677   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3679   [(set_attr "type" "shift")
3680    (set_attr "maybe_var_shift" "yes")])
3682 (define_insn_and_split "*rotl<mode>3_mask_dot"
3683   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3684         (compare:CC
3685           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3686                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3687                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3688                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3689           (const_int 0)))
3690    (clobber (match_scratch:GPR 0 "=r,r"))]
3691   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3692    && rs6000_gen_cell_microcode
3693    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3695   if (which_alternative == 0)
3696     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3697   else
3698     return "#";
3700   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3701   [(set (match_dup 0)
3702         (and:GPR (match_dup 4)
3703                  (match_dup 3)))
3704    (set (match_dup 5)
3705         (compare:CC (match_dup 0)
3706                     (const_int 0)))]
3707   ""
3708   [(set_attr "type" "shift")
3709    (set_attr "maybe_var_shift" "yes")
3710    (set_attr "dot" "yes")
3711    (set_attr "length" "4,8")])
3713 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3714   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3715         (compare:CC
3716           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3717                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3718                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3719                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3720           (const_int 0)))
3721    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3722         (and:GPR (match_dup 4)
3723                  (match_dup 3)))]
3724   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3725    && rs6000_gen_cell_microcode
3726    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3728   if (which_alternative == 0)
3729     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3730   else
3731     return "#";
3733   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3734   [(set (match_dup 0)
3735         (and:GPR (match_dup 4)
3736                  (match_dup 3)))
3737    (set (match_dup 5)
3738         (compare:CC (match_dup 0)
3739                     (const_int 0)))]
3740   ""
3741   [(set_attr "type" "shift")
3742    (set_attr "maybe_var_shift" "yes")
3743    (set_attr "dot" "yes")
3744    (set_attr "length" "4,8")])
3746 ; Special case for less-than-0.  We can do it with just one machine
3747 ; instruction, but the generic optimizers do not realise it is cheap.
3748 (define_insn "*lt0_disi"
3749   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3750         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3751                (const_int 0)))]
3752   "TARGET_POWERPC64"
3753   "rlwinm %0,%1,1,31,31"
3754   [(set_attr "type" "shift")])
3758 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3759 ; both are an AND so are the same precedence).
3760 (define_insn "*rotl<mode>3_insert"
3761   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3763                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3764                             (match_operand:SI 2 "const_int_operand" "n")])
3765                           (match_operand:GPR 3 "const_int_operand" "n"))
3766                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3767                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3768   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3769    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3771   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3773   [(set_attr "type" "insert")])
3774 ; FIXME: this needs an attr "size", so that the scheduler can see the
3775 ; difference between rlwimi and rldimi.  We also might want dot forms,
3776 ; but not for rlwimi on POWER4 and similar processors.
3778 (define_insn "*rotl<mode>3_insert_2"
3779   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3780         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3781                           (match_operand:GPR 6 "const_int_operand" "n"))
3782                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3783                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3784                             (match_operand:SI 2 "const_int_operand" "n")])
3785                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3786   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3787    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3789   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3791   [(set_attr "type" "insert")])
3793 ; There are also some forms without one of the ANDs.
3794 (define_insn "*rotl<mode>3_insert_3"
3795   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3796         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3797                           (match_operand:GPR 4 "const_int_operand" "n"))
3798                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3799                              (match_operand:SI 2 "const_int_operand" "n"))))]
3800   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3802   if (<MODE>mode == SImode)
3803     return "rlwimi %0,%1,%h2,0,31-%h2";
3804   else
3805     return "rldimi %0,%1,%H2,0";
3807   [(set_attr "type" "insert")])
3809 (define_insn "*rotl<mode>3_insert_4"
3810   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3811         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3812                           (match_operand:GPR 4 "const_int_operand" "n"))
3813                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3814                                (match_operand:SI 2 "const_int_operand" "n"))))]
3815   "<MODE>mode == SImode &&
3816    GET_MODE_PRECISION (<MODE>mode)
3817    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3819   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3820                          - INTVAL (operands[2]));
3821   if (<MODE>mode == SImode)
3822     return "rlwimi %0,%1,%h2,32-%h2,31";
3823   else
3824     return "rldimi %0,%1,%H2,64-%H2";
3826   [(set_attr "type" "insert")])
3829 ; This handles the important case of multiple-precision shifts.  There is
3830 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3831 (define_split
3832   [(set (match_operand:GPR 0 "gpc_reg_operand")
3833         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3834                              (match_operand:SI 3 "const_int_operand"))
3835                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3836                                (match_operand:SI 4 "const_int_operand"))))]
3837   "can_create_pseudo_p ()
3838    && INTVAL (operands[3]) + INTVAL (operands[4])
3839       >= GET_MODE_PRECISION (<MODE>mode)"
3840   [(set (match_dup 5)
3841         (lshiftrt:GPR (match_dup 2)
3842                       (match_dup 4)))
3843    (set (match_dup 0)
3844         (ior:GPR (and:GPR (match_dup 5)
3845                           (match_dup 6))
3846                  (ashift:GPR (match_dup 1)
3847                              (match_dup 3))))]
3849   unsigned HOST_WIDE_INT mask = 1;
3850   mask = (mask << INTVAL (operands[3])) - 1;
3851   operands[5] = gen_reg_rtx (<MODE>mode);
3852   operands[6] = GEN_INT (mask);
3855 (define_split
3856   [(set (match_operand:GPR 0 "gpc_reg_operand")
3857         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3858                                (match_operand:SI 4 "const_int_operand"))
3859                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3860                              (match_operand:SI 3 "const_int_operand"))))]
3861   "can_create_pseudo_p ()
3862    && INTVAL (operands[3]) + INTVAL (operands[4])
3863       >= GET_MODE_PRECISION (<MODE>mode)"
3864   [(set (match_dup 5)
3865         (lshiftrt:GPR (match_dup 2)
3866                       (match_dup 4)))
3867    (set (match_dup 0)
3868         (ior:GPR (and:GPR (match_dup 5)
3869                           (match_dup 6))
3870                  (ashift:GPR (match_dup 1)
3871                              (match_dup 3))))]
3873   unsigned HOST_WIDE_INT mask = 1;
3874   mask = (mask << INTVAL (operands[3])) - 1;
3875   operands[5] = gen_reg_rtx (<MODE>mode);
3876   operands[6] = GEN_INT (mask);
3880 ; Another important case is setting some bits to 1; we can do that with
3881 ; an insert instruction, in many cases.
3882 (define_insn_and_split "*ior<mode>_mask"
3883   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3884         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3885                  (match_operand:GPR 2 "const_int_operand" "n")))
3886    (clobber (match_scratch:GPR 3 "=r"))]
3887   "!logical_const_operand (operands[2], <MODE>mode)
3888    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3889   "#"
3890   "&& 1"
3891   [(set (match_dup 3)
3892         (const_int -1))
3893    (set (match_dup 0)
3894         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3895                                       (match_dup 4))
3896                           (match_dup 2))
3897                  (and:GPR (match_dup 1)
3898                           (match_dup 5))))]
3900   int nb, ne;
3901   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3902   if (GET_CODE (operands[3]) == SCRATCH)
3903     operands[3] = gen_reg_rtx (<MODE>mode);
3904   operands[4] = GEN_INT (ne);
3905   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3907   [(set_attr "type" "two")
3908    (set_attr "length" "8")])
3911 ;; Now the simple shifts.
3913 (define_insn "rotl<mode>3"
3914   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3915         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3916                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3917   ""
3918   "rotl<wd>%I2 %0,%1,%<hH>2"
3919   [(set_attr "type" "shift")
3920    (set_attr "maybe_var_shift" "yes")])
3922 (define_insn "*rotlsi3_64"
3923   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3924         (zero_extend:DI
3925             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3926                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3927   "TARGET_POWERPC64"
3928   "rotlw%I2 %0,%1,%h2"
3929   [(set_attr "type" "shift")
3930    (set_attr "maybe_var_shift" "yes")])
3932 (define_insn_and_split "*rotl<mode>3_dot"
3933   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3934         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3935                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3936                     (const_int 0)))
3937    (clobber (match_scratch:GPR 0 "=r,r"))]
3938   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3939   "@
3940    rotl<wd>%I2. %0,%1,%<hH>2
3941    #"
3942   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3943   [(set (match_dup 0)
3944         (rotate:GPR (match_dup 1)
3945                     (match_dup 2)))
3946    (set (match_dup 3)
3947         (compare:CC (match_dup 0)
3948                     (const_int 0)))]
3949   ""
3950   [(set_attr "type" "shift")
3951    (set_attr "maybe_var_shift" "yes")
3952    (set_attr "dot" "yes")
3953    (set_attr "length" "4,8")])
3955 (define_insn_and_split "*rotl<mode>3_dot2"
3956   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3957         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3958                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3959                     (const_int 0)))
3960    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3961         (rotate:GPR (match_dup 1)
3962                     (match_dup 2)))]
3963   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3964   "@
3965    rotl<wd>%I2. %0,%1,%<hH>2
3966    #"
3967   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3968   [(set (match_dup 0)
3969         (rotate:GPR (match_dup 1)
3970                     (match_dup 2)))
3971    (set (match_dup 3)
3972         (compare:CC (match_dup 0)
3973                     (const_int 0)))]
3974   ""
3975   [(set_attr "type" "shift")
3976    (set_attr "maybe_var_shift" "yes")
3977    (set_attr "dot" "yes")
3978    (set_attr "length" "4,8")])
3981 (define_insn "ashl<mode>3"
3982   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3983         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3984                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3985   ""
3986   "sl<wd>%I2 %0,%1,%<hH>2"
3987   [(set_attr "type" "shift")
3988    (set_attr "maybe_var_shift" "yes")])
3990 (define_insn "*ashlsi3_64"
3991   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3992         (zero_extend:DI
3993             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3994                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3995   "TARGET_POWERPC64"
3996   "slw%I2 %0,%1,%h2"
3997   [(set_attr "type" "shift")
3998    (set_attr "maybe_var_shift" "yes")])
4000 (define_insn_and_split "*ashl<mode>3_dot"
4001   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4002         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4003                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4004                     (const_int 0)))
4005    (clobber (match_scratch:GPR 0 "=r,r"))]
4006   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4007   "@
4008    sl<wd>%I2. %0,%1,%<hH>2
4009    #"
4010   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4011   [(set (match_dup 0)
4012         (ashift:GPR (match_dup 1)
4013                     (match_dup 2)))
4014    (set (match_dup 3)
4015         (compare:CC (match_dup 0)
4016                     (const_int 0)))]
4017   ""
4018   [(set_attr "type" "shift")
4019    (set_attr "maybe_var_shift" "yes")
4020    (set_attr "dot" "yes")
4021    (set_attr "length" "4,8")])
4023 (define_insn_and_split "*ashl<mode>3_dot2"
4024   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4025         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4026                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4027                     (const_int 0)))
4028    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4029         (ashift:GPR (match_dup 1)
4030                     (match_dup 2)))]
4031   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4032   "@
4033    sl<wd>%I2. %0,%1,%<hH>2
4034    #"
4035   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4036   [(set (match_dup 0)
4037         (ashift:GPR (match_dup 1)
4038                     (match_dup 2)))
4039    (set (match_dup 3)
4040         (compare:CC (match_dup 0)
4041                     (const_int 0)))]
4042   ""
4043   [(set_attr "type" "shift")
4044    (set_attr "maybe_var_shift" "yes")
4045    (set_attr "dot" "yes")
4046    (set_attr "length" "4,8")])
4048 ;; Pretend we have a memory form of extswsli until register allocation is done
4049 ;; so that we use LWZ to load the value from memory, instead of LWA.
4050 (define_insn_and_split "ashdi3_extswsli"
4051   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4052         (ashift:DI
4053          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4054          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4055   "TARGET_EXTSWSLI"
4056   "@
4057    extswsli %0,%1,%2
4058    #"
4059   "&& reload_completed && MEM_P (operands[1])"
4060   [(set (match_dup 3)
4061         (match_dup 1))
4062    (set (match_dup 0)
4063         (ashift:DI (sign_extend:DI (match_dup 3))
4064                    (match_dup 2)))]
4066   operands[3] = gen_lowpart (SImode, operands[0]);
4068   [(set_attr "type" "shift")
4069    (set_attr "maybe_var_shift" "no")])
4072 (define_insn_and_split "ashdi3_extswsli_dot"
4073   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4074         (compare:CC
4075          (ashift:DI
4076           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4077           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4078          (const_int 0)))
4079    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4080   "TARGET_EXTSWSLI"
4081   "@
4082    extswsli. %0,%1,%2
4083    #
4084    #
4085    #"
4086   "&& reload_completed
4087    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4088        || memory_operand (operands[1], SImode))"
4089   [(pc)]
4091   rtx dest = operands[0];
4092   rtx src = operands[1];
4093   rtx shift = operands[2];
4094   rtx cr = operands[3];
4095   rtx src2;
4097   if (!MEM_P (src))
4098     src2 = src;
4099   else
4100     {
4101       src2 = gen_lowpart (SImode, dest);
4102       emit_move_insn (src2, src);
4103     }
4105   if (REGNO (cr) == CR0_REGNO)
4106     {
4107       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4108       DONE;
4109     }
4111   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4112   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4113   DONE;
4115   [(set_attr "type" "shift")
4116    (set_attr "maybe_var_shift" "no")
4117    (set_attr "dot" "yes")
4118    (set_attr "length" "4,8,8,12")])
4120 (define_insn_and_split "ashdi3_extswsli_dot2"
4121   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4122         (compare:CC
4123          (ashift:DI
4124           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4125           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4126          (const_int 0)))
4127    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4128         (ashift:DI (sign_extend:DI (match_dup 1))
4129                    (match_dup 2)))]
4130   "TARGET_EXTSWSLI"
4131   "@
4132    extswsli. %0,%1,%2
4133    #
4134    #
4135    #"
4136   "&& reload_completed
4137    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4138        || memory_operand (operands[1], SImode))"
4139   [(pc)]
4141   rtx dest = operands[0];
4142   rtx src = operands[1];
4143   rtx shift = operands[2];
4144   rtx cr = operands[3];
4145   rtx src2;
4147   if (!MEM_P (src))
4148     src2 = src;
4149   else
4150     {
4151       src2 = gen_lowpart (SImode, dest);
4152       emit_move_insn (src2, src);
4153     }
4155   if (REGNO (cr) == CR0_REGNO)
4156     {
4157       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4158       DONE;
4159     }
4161   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4162   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4163   DONE;
4165   [(set_attr "type" "shift")
4166    (set_attr "maybe_var_shift" "no")
4167    (set_attr "dot" "yes")
4168    (set_attr "length" "4,8,8,12")])
4170 (define_insn "lshr<mode>3"
4171   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4172         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4173                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4174   ""
4175   "sr<wd>%I2 %0,%1,%<hH>2"
4176   [(set_attr "type" "shift")
4177    (set_attr "maybe_var_shift" "yes")])
4179 (define_insn "*lshrsi3_64"
4180   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4181         (zero_extend:DI
4182             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4183                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4184   "TARGET_POWERPC64"
4185   "srw%I2 %0,%1,%h2"
4186   [(set_attr "type" "shift")
4187    (set_attr "maybe_var_shift" "yes")])
4189 (define_insn_and_split "*lshr<mode>3_dot"
4190   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4191         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4192                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4193                     (const_int 0)))
4194    (clobber (match_scratch:GPR 0 "=r,r"))]
4195   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4196   "@
4197    sr<wd>%I2. %0,%1,%<hH>2
4198    #"
4199   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4200   [(set (match_dup 0)
4201         (lshiftrt:GPR (match_dup 1)
4202                       (match_dup 2)))
4203    (set (match_dup 3)
4204         (compare:CC (match_dup 0)
4205                     (const_int 0)))]
4206   ""
4207   [(set_attr "type" "shift")
4208    (set_attr "maybe_var_shift" "yes")
4209    (set_attr "dot" "yes")
4210    (set_attr "length" "4,8")])
4212 (define_insn_and_split "*lshr<mode>3_dot2"
4213   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4214         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4215                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4216                     (const_int 0)))
4217    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4218         (lshiftrt:GPR (match_dup 1)
4219                       (match_dup 2)))]
4220   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4221   "@
4222    sr<wd>%I2. %0,%1,%<hH>2
4223    #"
4224   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4225   [(set (match_dup 0)
4226         (lshiftrt:GPR (match_dup 1)
4227                       (match_dup 2)))
4228    (set (match_dup 3)
4229         (compare:CC (match_dup 0)
4230                     (const_int 0)))]
4231   ""
4232   [(set_attr "type" "shift")
4233    (set_attr "maybe_var_shift" "yes")
4234    (set_attr "dot" "yes")
4235    (set_attr "length" "4,8")])
4238 (define_insn "ashr<mode>3"
4239   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4240         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4241                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4242    (clobber (reg:GPR CA_REGNO))]
4243   ""
4244   "sra<wd>%I2 %0,%1,%<hH>2"
4245   [(set_attr "type" "shift")
4246    (set_attr "maybe_var_shift" "yes")])
4248 (define_insn "*ashrsi3_64"
4249   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4250         (sign_extend:DI
4251             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4252                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4253    (clobber (reg:SI CA_REGNO))]
4254   "TARGET_POWERPC64"
4255   "sraw%I2 %0,%1,%h2"
4256   [(set_attr "type" "shift")
4257    (set_attr "maybe_var_shift" "yes")])
4259 (define_insn_and_split "*ashr<mode>3_dot"
4260   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4261         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4262                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4263                     (const_int 0)))
4264    (clobber (match_scratch:GPR 0 "=r,r"))
4265    (clobber (reg:GPR CA_REGNO))]
4266   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4267   "@
4268    sra<wd>%I2. %0,%1,%<hH>2
4269    #"
4270   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4271   [(parallel [(set (match_dup 0)
4272                    (ashiftrt:GPR (match_dup 1)
4273                                  (match_dup 2)))
4274               (clobber (reg:GPR CA_REGNO))])
4275    (set (match_dup 3)
4276         (compare:CC (match_dup 0)
4277                     (const_int 0)))]
4278   ""
4279   [(set_attr "type" "shift")
4280    (set_attr "maybe_var_shift" "yes")
4281    (set_attr "dot" "yes")
4282    (set_attr "length" "4,8")])
4284 (define_insn_and_split "*ashr<mode>3_dot2"
4285   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4286         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4287                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4288                     (const_int 0)))
4289    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4290         (ashiftrt:GPR (match_dup 1)
4291                       (match_dup 2)))
4292    (clobber (reg:GPR CA_REGNO))]
4293   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4294   "@
4295    sra<wd>%I2. %0,%1,%<hH>2
4296    #"
4297   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4298   [(parallel [(set (match_dup 0)
4299                    (ashiftrt:GPR (match_dup 1)
4300                                  (match_dup 2)))
4301               (clobber (reg:GPR CA_REGNO))])
4302    (set (match_dup 3)
4303         (compare:CC (match_dup 0)
4304                     (const_int 0)))]
4305   ""
4306   [(set_attr "type" "shift")
4307    (set_attr "maybe_var_shift" "yes")
4308    (set_attr "dot" "yes")
4309    (set_attr "length" "4,8")])
4311 ;; Builtins to replace a division to generate FRE reciprocal estimate
4312 ;; instructions and the necessary fixup instructions
4313 (define_expand "recip<mode>3"
4314   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4315    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4316    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4317   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4319    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4320    DONE;
4323 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4324 ;; hardware division.  This is only done before register allocation and with
4325 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4326 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4327 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4328 (define_split
4329   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4330         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4331                     (match_operand 2 "gpc_reg_operand" "")))]
4332   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4333    && can_create_pseudo_p () && flag_finite_math_only
4334    && !flag_trapping_math && flag_reciprocal_math"
4335   [(const_int 0)]
4337   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4338   DONE;
4341 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4342 ;; appropriate fixup.
4343 (define_expand "rsqrt<mode>2"
4344   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4345    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4346   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4348   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4349   DONE;
4352 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4353 ;; modes here, and also add in conditional vsx/power8-vector support to access
4354 ;; values in the traditional Altivec registers if the appropriate
4355 ;; -mupper-regs-{df,sf} option is enabled.
4357 (define_expand "abs<mode>2"
4358   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4359         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4360   "TARGET_<MODE>_INSN"
4361   "")
4363 (define_insn "*abs<mode>2_fpr"
4364   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4365         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4366   "TARGET_<MODE>_FPR"
4367   "@
4368    fabs %0,%1
4369    xsabsdp %x0,%x1"
4370   [(set_attr "type" "fpsimple")
4371    (set_attr "fp_type" "fp_addsub_<Fs>")])
4373 (define_insn "*nabs<mode>2_fpr"
4374   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4375         (neg:SFDF
4376          (abs:SFDF
4377           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4378   "TARGET_<MODE>_FPR"
4379   "@
4380    fnabs %0,%1
4381    xsnabsdp %x0,%x1"
4382   [(set_attr "type" "fpsimple")
4383    (set_attr "fp_type" "fp_addsub_<Fs>")])
4385 (define_expand "neg<mode>2"
4386   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4387         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4388   "TARGET_<MODE>_INSN"
4389   "")
4391 (define_insn "*neg<mode>2_fpr"
4392   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4393         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4394   "TARGET_<MODE>_FPR"
4395   "@
4396    fneg %0,%1
4397    xsnegdp %x0,%x1"
4398   [(set_attr "type" "fpsimple")
4399    (set_attr "fp_type" "fp_addsub_<Fs>")])
4401 (define_expand "add<mode>3"
4402   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4403         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4404                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4405   "TARGET_<MODE>_INSN"
4406   "")
4408 (define_insn "*add<mode>3_fpr"
4409   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4410         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4411                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4412   "TARGET_<MODE>_FPR"
4413   "@
4414    fadd<Ftrad> %0,%1,%2
4415    xsadd<Fvsx> %x0,%x1,%x2"
4416   [(set_attr "type" "fp")
4417    (set_attr "fp_type" "fp_addsub_<Fs>")])
4419 (define_expand "sub<mode>3"
4420   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4421         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4422                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4423   "TARGET_<MODE>_INSN"
4424   "")
4426 (define_insn "*sub<mode>3_fpr"
4427   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4428         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4429                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4430   "TARGET_<MODE>_FPR"
4431   "@
4432    fsub<Ftrad> %0,%1,%2
4433    xssub<Fvsx> %x0,%x1,%x2"
4434   [(set_attr "type" "fp")
4435    (set_attr "fp_type" "fp_addsub_<Fs>")])
4437 (define_expand "mul<mode>3"
4438   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4439         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4440                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4441   "TARGET_<MODE>_INSN"
4442   "")
4444 (define_insn "*mul<mode>3_fpr"
4445   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4446         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4447                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4448   "TARGET_<MODE>_FPR"
4449   "@
4450    fmul<Ftrad> %0,%1,%2
4451    xsmul<Fvsx> %x0,%x1,%x2"
4452   [(set_attr "type" "dmul")
4453    (set_attr "fp_type" "fp_mul_<Fs>")])
4455 (define_expand "div<mode>3"
4456   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4457         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4458                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4459   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4460   "")
4462 (define_insn "*div<mode>3_fpr"
4463   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4464         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4465                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4466   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4467   "@
4468    fdiv<Ftrad> %0,%1,%2
4469    xsdiv<Fvsx> %x0,%x1,%x2"
4470   [(set_attr "type" "<Fs>div")
4471    (set_attr "fp_type" "fp_div_<Fs>")])
4473 (define_insn "*sqrt<mode>2_internal"
4474   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4475         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4476   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4477    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4478   "@
4479    fsqrt<Ftrad> %0,%1
4480    xssqrt<Fvsx> %x0,%x1"
4481   [(set_attr "type" "<Fs>sqrt")
4482    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4484 (define_expand "sqrt<mode>2"
4485   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4486         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4487   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4488    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4490   if (<MODE>mode == SFmode
4491       && TARGET_RECIP_PRECISION
4492       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4493       && !optimize_function_for_size_p (cfun)
4494       && flag_finite_math_only && !flag_trapping_math
4495       && flag_unsafe_math_optimizations)
4496     {
4497       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4498       DONE;
4499     }
4502 ;; Floating point reciprocal approximation
4503 (define_insn "fre<Fs>"
4504   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4505         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4506                      UNSPEC_FRES))]
4507   "TARGET_<FFRE>"
4508   "@
4509    fre<Ftrad> %0,%1
4510    xsre<Fvsx> %x0,%x1"
4511   [(set_attr "type" "fp")])
4513 (define_insn "*rsqrt<mode>2"
4514   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4515         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4516                      UNSPEC_RSQRT))]
4517   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4518   "@
4519    frsqrte<Ftrad> %0,%1
4520    xsrsqrte<Fvsx> %x0,%x1"
4521   [(set_attr "type" "fp")])
4523 ;; Floating point comparisons
4524 (define_insn "*cmp<mode>_fpr"
4525   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4526         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4527                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4528   "TARGET_<MODE>_FPR"
4529   "@
4530    fcmpu %0,%1,%2
4531    xscmpudp %0,%x1,%x2"
4532   [(set_attr "type" "fpcompare")])
4534 ;; Floating point conversions
4535 (define_expand "extendsfdf2"
4536   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4537         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4538   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4539   "")
4541 (define_insn_and_split "*extendsfdf2_fpr"
4542   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4543         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4544   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4545   "@
4546    #
4547    fmr %0,%1
4548    lfs%U1%X1 %0,%1
4549    #
4550    xscpsgndp %x0,%x1,%x1
4551    lxsspx %x0,%y1
4552    lxssp %0,%1"
4553   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4554   [(const_int 0)]
4556   emit_note (NOTE_INSN_DELETED);
4557   DONE;
4559   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4561 (define_expand "truncdfsf2"
4562   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4563         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4564   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4565   "")
4567 (define_insn "*truncdfsf2_fpr"
4568   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4569         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4570   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4571   "@
4572    frsp %0,%1
4573    xsrsp %x0,%x1"
4574   [(set_attr "type" "fp")])
4576 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4577 ;; builtins.c and optabs.c that are not correct for IBM long double
4578 ;; when little-endian.
4579 (define_expand "signbit<mode>2"
4580   [(set (match_dup 2)
4581         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4582    (set (match_dup 3)
4583         (subreg:DI (match_dup 2) 0))
4584    (set (match_dup 4)
4585         (match_dup 5))
4586    (set (match_operand:SI 0 "gpc_reg_operand" "")
4587         (match_dup 6))]
4588   "TARGET_HARD_FLOAT
4589    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4590    && (!FLOAT128_IEEE_P (<MODE>mode)
4591        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4593   if (FLOAT128_IEEE_P (<MODE>mode))
4594     {
4595       if (<MODE>mode == KFmode)
4596         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4597       else if (<MODE>mode == TFmode)
4598         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4599       else
4600         gcc_unreachable ();
4601       DONE;
4602     }
4603   operands[2] = gen_reg_rtx (DFmode);
4604   operands[3] = gen_reg_rtx (DImode);
4605   if (TARGET_POWERPC64)
4606     {
4607       operands[4] = gen_reg_rtx (DImode);
4608       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4609       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4610                                     WORDS_BIG_ENDIAN ? 4 : 0);
4611     }
4612   else
4613     {
4614       operands[4] = gen_reg_rtx (SImode);
4615       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4616                                     WORDS_BIG_ENDIAN ? 0 : 4);
4617       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4618     }
4621 (define_expand "copysign<mode>3"
4622   [(set (match_dup 3)
4623         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4624    (set (match_dup 4)
4625         (neg:SFDF (abs:SFDF (match_dup 1))))
4626    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4627         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4628                                (match_dup 5))
4629                          (match_dup 3)
4630                          (match_dup 4)))]
4631   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4632    && ((TARGET_PPC_GFXOPT
4633         && !HONOR_NANS (<MODE>mode)
4634         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4635        || TARGET_CMPB
4636        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4638   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4639     {
4640       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4641                                              operands[2]));
4642       DONE;
4643     }
4645    operands[3] = gen_reg_rtx (<MODE>mode);
4646    operands[4] = gen_reg_rtx (<MODE>mode);
4647    operands[5] = CONST0_RTX (<MODE>mode);
4648   })
4650 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4651 ;; and load.
4652 (define_insn_and_split "signbit<mode>2_dm"
4653   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4654         (unspec:SI
4655          [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4656          UNSPEC_SIGNBIT))]
4657   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4658   "#"
4659   "&& reload_completed"
4660   [(const_int 0)]
4662   rs6000_split_signbit (operands[0], operands[1]);
4663   DONE;
4665  [(set_attr "length" "8,8,12")
4666   (set_attr "type" "mftgpr,load,integer")])
4668 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4669 ;; point types, which makes normal SUBREG's problematical. Instead use a
4670 ;; special pattern to avoid using a normal movdi.
4671 (define_insn "signbit<mode>2_dm2"
4672   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4673         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4674                     (const_int 0)]
4675                    UNSPEC_SIGNBIT))]
4676   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4677   "mfvsrd %0,%x1"
4678  [(set_attr "type" "mftgpr")])
4681 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4682 ;; compiler from optimizing -0.0
4683 (define_insn "copysign<mode>3_fcpsgn"
4684   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4685         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4686                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4687                      UNSPEC_COPYSIGN))]
4688   "TARGET_<MODE>_FPR && TARGET_CMPB"
4689   "@
4690    fcpsgn %0,%2,%1
4691    xscpsgndp %x0,%x2,%x1"
4692   [(set_attr "type" "fpsimple")])
4694 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4695 ;; fsel instruction and some auxiliary computations.  Then we just have a
4696 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4697 ;; combine.
4698 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4699 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4700 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4701 ;; define_splits to make them if made by combine.  On VSX machines we have the
4702 ;; min/max instructions.
4704 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4705 ;; to allow either DF/SF to use only traditional registers.
4707 (define_expand "s<minmax><mode>3"
4708   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4709         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4710                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4711   "TARGET_MINMAX_<MODE>"
4713   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4714   DONE;
4717 (define_insn "*s<minmax><mode>3_vsx"
4718   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4719         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4720                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4721   "TARGET_VSX && TARGET_<MODE>_FPR"
4723   return (TARGET_P9_MINMAX
4724           ? "xs<minmax>cdp %x0,%x1,%x2"
4725           : "xs<minmax>dp %x0,%x1,%x2");
4727   [(set_attr "type" "fp")])
4729 ;; The conditional move instructions allow us to perform max and min operations
4730 ;; even when we don't have the appropriate max/min instruction using the FSEL
4731 ;; instruction.
4733 (define_insn_and_split "*s<minmax><mode>3_fpr"
4734   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4735         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4736                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4737   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4738   "#"
4739   "&& 1"
4740   [(const_int 0)]
4742   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4743   DONE;
4746 (define_expand "mov<mode>cc"
4747    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4748          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4749                            (match_operand:GPR 2 "gpc_reg_operand" "")
4750                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4751   "TARGET_ISEL<sel>"
4752   "
4754   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4755     DONE;
4756   else
4757     FAIL;
4760 ;; We use the BASE_REGS for the isel input operands because, if rA is
4761 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4762 ;; because we may switch the operands and rB may end up being rA.
4764 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4765 ;; leave out the mode in operand 4 and use one pattern, but reload can
4766 ;; change the mode underneath our feet and then gets confused trying
4767 ;; to reload the value.
4768 (define_insn "isel_signed_<mode>"
4769   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4770         (if_then_else:GPR
4771          (match_operator 1 "scc_comparison_operator"
4772                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4773                           (const_int 0)])
4774          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4775          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4776   "TARGET_ISEL<sel>"
4777   "*
4778 { return output_isel (operands); }"
4779   [(set_attr "type" "isel")
4780    (set_attr "length" "4")])
4782 (define_insn "isel_unsigned_<mode>"
4783   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4784         (if_then_else:GPR
4785          (match_operator 1 "scc_comparison_operator"
4786                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4787                           (const_int 0)])
4788          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4789          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4790   "TARGET_ISEL<sel>"
4791   "*
4792 { return output_isel (operands); }"
4793   [(set_attr "type" "isel")
4794    (set_attr "length" "4")])
4796 ;; These patterns can be useful for combine; they let combine know that
4797 ;; isel can handle reversed comparisons so long as the operands are
4798 ;; registers.
4800 (define_insn "*isel_reversed_signed_<mode>"
4801   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4802         (if_then_else:GPR
4803          (match_operator 1 "scc_rev_comparison_operator"
4804                          [(match_operand:CC 4 "cc_reg_operand" "y")
4805                           (const_int 0)])
4806          (match_operand:GPR 2 "gpc_reg_operand" "b")
4807          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4808   "TARGET_ISEL<sel>"
4809   "*
4810 { return output_isel (operands); }"
4811   [(set_attr "type" "isel")
4812    (set_attr "length" "4")])
4814 (define_insn "*isel_reversed_unsigned_<mode>"
4815   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4816         (if_then_else:GPR
4817          (match_operator 1 "scc_rev_comparison_operator"
4818                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4819                           (const_int 0)])
4820          (match_operand:GPR 2 "gpc_reg_operand" "b")
4821          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4822   "TARGET_ISEL<sel>"
4823   "*
4824 { return output_isel (operands); }"
4825   [(set_attr "type" "isel")
4826    (set_attr "length" "4")])
4828 ;; Floating point conditional move
4829 (define_expand "mov<mode>cc"
4830    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4831          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4832                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4833                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4834   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4835   "
4837   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4838     DONE;
4839   else
4840     FAIL;
4843 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4844   [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4845         (if_then_else:SFDF
4846          (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4847              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4848          (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4849          (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4850   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4851   "fsel %0,%1,%2,%3"
4852   [(set_attr "type" "fp")])
4854 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4855   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4856         (if_then_else:SFDF
4857          (match_operator:CCFP 1 "fpmask_comparison_operator"
4858                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4859                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4860          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4861          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4862    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4863   "TARGET_P9_MINMAX"
4864   "#"
4865   ""
4866   [(set (match_dup 6)
4867         (if_then_else:V2DI (match_dup 1)
4868                            (match_dup 7)
4869                            (match_dup 8)))
4870    (set (match_dup 0)
4871         (if_then_else:SFDF (ne (match_dup 6)
4872                                (match_dup 8))
4873                            (match_dup 4)
4874                            (match_dup 5)))]
4876   if (GET_CODE (operands[6]) == SCRATCH)
4877     operands[6] = gen_reg_rtx (V2DImode);
4879   operands[7] = CONSTM1_RTX (V2DImode);
4880   operands[8] = CONST0_RTX (V2DImode);
4882  [(set_attr "length" "8")
4883   (set_attr "type" "vecperm")])
4885 ;; Handle inverting the fpmask comparisons.
4886 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4887   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4888         (if_then_else:SFDF
4889          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4890                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4891                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4892          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4893          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4894    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4895   "TARGET_P9_MINMAX"
4896   "#"
4897   "&& 1"
4898   [(set (match_dup 6)
4899         (if_then_else:V2DI (match_dup 9)
4900                            (match_dup 7)
4901                            (match_dup 8)))
4902    (set (match_dup 0)
4903         (if_then_else:SFDF (ne (match_dup 6)
4904                                (match_dup 8))
4905                            (match_dup 5)
4906                            (match_dup 4)))]
4908   rtx op1 = operands[1];
4909   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
4911   if (GET_CODE (operands[6]) == SCRATCH)
4912     operands[6] = gen_reg_rtx (V2DImode);
4914   operands[7] = CONSTM1_RTX (V2DImode);
4915   operands[8] = CONST0_RTX (V2DImode);
4917   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
4919  [(set_attr "length" "8")
4920   (set_attr "type" "vecperm")])
4922 (define_insn "*fpmask<mode>"
4923   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4924         (if_then_else:V2DI
4925          (match_operator:CCFP 1 "fpmask_comparison_operator"
4926                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4927                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4928          (match_operand:V2DI 4 "all_ones_constant" "")
4929          (match_operand:V2DI 5 "zero_constant" "")))]
4930   "TARGET_P9_MINMAX"
4931   "xscmp%V1dp %x0,%x2,%x3"
4932   [(set_attr "type" "fpcompare")])
4934 (define_insn "*xxsel<mode>"
4935   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4936         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4937                                (match_operand:V2DI 2 "zero_constant" ""))
4938                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4939                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4940   "TARGET_P9_MINMAX"
4941   "xxsel %x0,%x4,%x3,%x1"
4942   [(set_attr "type" "vecmove")])
4945 ;; Conversions to and from floating-point.
4947 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4948 ; don't want to support putting SImode in FPR registers.
4949 (define_insn "lfiwax"
4950   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4951         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4952                    UNSPEC_LFIWAX))]
4953   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4954   "@
4955    lfiwax %0,%y1
4956    lxsiwax %x0,%y1
4957    mtvsrwa %x0,%1"
4958   [(set_attr "type" "fpload,fpload,mffgpr")])
4960 ; This split must be run before register allocation because it allocates the
4961 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4962 ; it earlier to allow for the combiner to merge insns together where it might
4963 ; not be needed and also in case the insns are deleted as dead code.
4965 (define_insn_and_split "floatsi<mode>2_lfiwax"
4966   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4967         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4968    (clobber (match_scratch:DI 2 "=wi"))]
4969   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4970    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4971   "#"
4972   ""
4973   [(pc)]
4974   "
4976   rtx dest = operands[0];
4977   rtx src = operands[1];
4978   rtx tmp;
4980   if (!MEM_P (src) && TARGET_POWERPC64
4981       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4982     tmp = convert_to_mode (DImode, src, false);
4983   else
4984     {
4985       tmp = operands[2];
4986       if (GET_CODE (tmp) == SCRATCH)
4987         tmp = gen_reg_rtx (DImode);
4988       if (MEM_P (src))
4989         {
4990           src = rs6000_address_for_fpconvert (src);
4991           emit_insn (gen_lfiwax (tmp, src));
4992         }
4993       else
4994         {
4995           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4996           emit_move_insn (stack, src);
4997           emit_insn (gen_lfiwax (tmp, stack));
4998         }
4999     }
5000   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5001   DONE;
5003   [(set_attr "length" "12")
5004    (set_attr "type" "fpload")])
5006 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5007   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5008         (float:SFDF
5009          (sign_extend:DI
5010           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5011    (clobber (match_scratch:DI 2 "=wi"))]
5012   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5013    && <SI_CONVERT_FP>"
5014   "#"
5015   ""
5016   [(pc)]
5017   "
5019   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5020   if (GET_CODE (operands[2]) == SCRATCH)
5021     operands[2] = gen_reg_rtx (DImode);
5022   emit_insn (gen_lfiwax (operands[2], operands[1]));
5023   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5024   DONE;
5026   [(set_attr "length" "8")
5027    (set_attr "type" "fpload")])
5029 (define_insn "lfiwzx"
5030   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5031         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5032                    UNSPEC_LFIWZX))]
5033   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5034   "@
5035    lfiwzx %0,%y1
5036    lxsiwzx %x0,%y1
5037    mtvsrwz %x0,%1"
5038   [(set_attr "type" "fpload,fpload,mftgpr")])
5040 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5041   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5042         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5043    (clobber (match_scratch:DI 2 "=wi"))]
5044   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5045    && <SI_CONVERT_FP>"
5046   "#"
5047   ""
5048   [(pc)]
5049   "
5051   rtx dest = operands[0];
5052   rtx src = operands[1];
5053   rtx tmp;
5055   if (!MEM_P (src) && TARGET_POWERPC64
5056       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5057     tmp = convert_to_mode (DImode, src, true);
5058   else
5059     {
5060       tmp = operands[2];
5061       if (GET_CODE (tmp) == SCRATCH)
5062         tmp = gen_reg_rtx (DImode);
5063       if (MEM_P (src))
5064         {
5065           src = rs6000_address_for_fpconvert (src);
5066           emit_insn (gen_lfiwzx (tmp, src));
5067         }
5068       else
5069         {
5070           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5071           emit_move_insn (stack, src);
5072           emit_insn (gen_lfiwzx (tmp, stack));
5073         }
5074     }
5075   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5076   DONE;
5078   [(set_attr "length" "12")
5079    (set_attr "type" "fpload")])
5081 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5082   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5083         (unsigned_float:SFDF
5084          (zero_extend:DI
5085           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5086    (clobber (match_scratch:DI 2 "=wi"))]
5087   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5088    && <SI_CONVERT_FP>"
5089   "#"
5090   ""
5091   [(pc)]
5092   "
5094   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5095   if (GET_CODE (operands[2]) == SCRATCH)
5096     operands[2] = gen_reg_rtx (DImode);
5097   emit_insn (gen_lfiwzx (operands[2], operands[1]));
5098   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5099   DONE;
5101   [(set_attr "length" "8")
5102    (set_attr "type" "fpload")])
5104 ; For each of these conversions, there is a define_expand, a define_insn
5105 ; with a '#' template, and a define_split (with C code).  The idea is
5106 ; to allow constant folding with the template of the define_insn,
5107 ; then to have the insns split later (between sched1 and final).
5109 (define_expand "floatsidf2"
5110   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5111                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5112               (use (match_dup 2))
5113               (use (match_dup 3))
5114               (clobber (match_dup 4))
5115               (clobber (match_dup 5))
5116               (clobber (match_dup 6))])]
5117   "TARGET_HARD_FLOAT 
5118    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5119   "
5121   if (TARGET_E500_DOUBLE)
5122     {
5123       if (!REG_P (operands[1]))
5124         operands[1] = force_reg (SImode, operands[1]);
5125       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5126       DONE;
5127     }
5128   else if (TARGET_LFIWAX && TARGET_FCFID)
5129     {
5130       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5131       DONE;
5132     }
5133   else if (TARGET_FCFID)
5134     {
5135       rtx dreg = operands[1];
5136       if (!REG_P (dreg))
5137         dreg = force_reg (SImode, dreg);
5138       dreg = convert_to_mode (DImode, dreg, false);
5139       emit_insn (gen_floatdidf2 (operands[0], dreg));
5140       DONE;
5141     }
5143   if (!REG_P (operands[1]))
5144     operands[1] = force_reg (SImode, operands[1]);
5145   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5146   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5147   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5148   operands[5] = gen_reg_rtx (DFmode);
5149   operands[6] = gen_reg_rtx (SImode);
5152 (define_insn_and_split "*floatsidf2_internal"
5153   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5154         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5155    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5156    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5157    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5158    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5159    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5160   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5161   "#"
5162   ""
5163   [(pc)]
5164   "
5166   rtx lowword, highword;
5167   gcc_assert (MEM_P (operands[4]));
5168   highword = adjust_address (operands[4], SImode, 0);
5169   lowword = adjust_address (operands[4], SImode, 4);
5170   if (! WORDS_BIG_ENDIAN)
5171     std::swap (lowword, highword);
5173   emit_insn (gen_xorsi3 (operands[6], operands[1],
5174                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5175   emit_move_insn (lowword, operands[6]);
5176   emit_move_insn (highword, operands[2]);
5177   emit_move_insn (operands[5], operands[4]);
5178   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5179   DONE;
5181   [(set_attr "length" "24")
5182    (set_attr "type" "fp")])
5184 ;; If we don't have a direct conversion to single precision, don't enable this
5185 ;; conversion for 32-bit without fast math, because we don't have the insn to
5186 ;; generate the fixup swizzle to avoid double rounding problems.
5187 (define_expand "floatunssisf2"
5188   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5189         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5190   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5191    && (!TARGET_FPRS
5192        || (TARGET_FPRS
5193            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5194                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5195                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5196   "
5198   if (!TARGET_FPRS)
5199     {
5200       if (!REG_P (operands[1]))
5201         operands[1] = force_reg (SImode, operands[1]);
5202     }
5203   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5204     {
5205       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5206       DONE;
5207     }
5208   else
5209     {
5210       rtx dreg = operands[1];
5211       if (!REG_P (dreg))
5212         dreg = force_reg (SImode, dreg);
5213       dreg = convert_to_mode (DImode, dreg, true);
5214       emit_insn (gen_floatdisf2 (operands[0], dreg));
5215       DONE;
5216     }
5219 (define_expand "floatunssidf2"
5220   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5221                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5222               (use (match_dup 2))
5223               (use (match_dup 3))
5224               (clobber (match_dup 4))
5225               (clobber (match_dup 5))])]
5226   "TARGET_HARD_FLOAT
5227    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5228   "
5230   if (TARGET_E500_DOUBLE)
5231     {
5232       if (!REG_P (operands[1]))
5233         operands[1] = force_reg (SImode, operands[1]);
5234       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5235       DONE;
5236     }
5237   else if (TARGET_LFIWZX && TARGET_FCFID)
5238     {
5239       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5240       DONE;
5241     }
5242   else if (TARGET_FCFID)
5243     {
5244       rtx dreg = operands[1];
5245       if (!REG_P (dreg))
5246         dreg = force_reg (SImode, dreg);
5247       dreg = convert_to_mode (DImode, dreg, true);
5248       emit_insn (gen_floatdidf2 (operands[0], dreg));
5249       DONE;
5250     }
5252   if (!REG_P (operands[1]))
5253     operands[1] = force_reg (SImode, operands[1]);
5254   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5255   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5256   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5257   operands[5] = gen_reg_rtx (DFmode);
5260 (define_insn_and_split "*floatunssidf2_internal"
5261   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5262         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5263    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5264    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5265    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5266    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5267   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5268    && !(TARGET_FCFID && TARGET_POWERPC64)"
5269   "#"
5270   ""
5271   [(pc)]
5272   "
5274   rtx lowword, highword;
5275   gcc_assert (MEM_P (operands[4]));
5276   highword = adjust_address (operands[4], SImode, 0);
5277   lowword = adjust_address (operands[4], SImode, 4);
5278   if (! WORDS_BIG_ENDIAN)
5279     std::swap (lowword, highword);
5281   emit_move_insn (lowword, operands[1]);
5282   emit_move_insn (highword, operands[2]);
5283   emit_move_insn (operands[5], operands[4]);
5284   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5285   DONE;
5287   [(set_attr "length" "20")
5288    (set_attr "type" "fp")])
5290 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5291 ;; vector registers.  At the moment, QI/HImode are not allowed in floating
5292 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5293 ;; half-word instructions.
5295 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5296   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5297                    (float:FP_ISA3
5298                     (match_operand:QHI 1 "input_operand")))
5299               (clobber (match_scratch:DI 2))
5300               (clobber (match_scratch:DI 3))])]
5301   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5303   if (MEM_P (operands[1]))
5304     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5307 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5308   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5309         (float:FP_ISA3
5310          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5311    (clobber (match_scratch:DI 2 "=wi,v"))
5312    (clobber (match_scratch:DI 3 "=r,X"))]
5313   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5314    && TARGET_UPPER_REGS_DI"
5315   "#"
5316   "&& reload_completed"
5317   [(const_int 0)]
5319   rtx result = operands[0];
5320   rtx input = operands[1];
5321   rtx di = operands[2];
5323   if (!MEM_P (input))
5324     {
5325       rtx tmp = operands[3];
5326       emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5327       emit_move_insn (di, tmp);
5328     }
5329   else
5330     {
5331       machine_mode vmode;
5332       rtx di_vector;
5334       emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5336       if (<MODE>mode == QImode)
5337         vmode = V16QImode;
5338       else if (<MODE>mode == HImode)
5339         vmode = V8HImode;
5340       else
5341         gcc_unreachable ();
5343       di_vector = gen_rtx_REG (vmode, REGNO (di));
5344       emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5345     }
5347   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5348   DONE;
5351 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5352   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5353                    (unsigned_float:FP_ISA3
5354                     (match_operand:QHI 1 "input_operand" "")))
5355               (clobber (match_scratch:DI 2 ""))
5356               (clobber (match_scratch:DI 3 ""))])]
5357   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5359   if (MEM_P (operands[1]))
5360     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5363 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5364   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5365         (unsigned_float:FP_ISA3
5366          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5367    (clobber (match_scratch:DI 2 "=wi,wi"))
5368    (clobber (match_scratch:DI 3 "=r,X"))]
5369   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5370   "#"
5371   "&& reload_completed"
5372   [(const_int 0)]
5374   rtx result = operands[0];
5375   rtx input = operands[1];
5376   rtx di = operands[2];
5377   rtx tmp = operands[3];
5379   if (!MEM_P (input))
5380     {
5381       emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5382       emit_move_insn (di, tmp);
5383     }
5384   else
5385     emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5387   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5388   DONE;
5391 (define_expand "fix_trunc<mode>si2"
5392   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5393         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5394   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5395   "
5397   if (!<E500_CONVERT>)
5398     {
5399       rtx src = force_reg (<MODE>mode, operands[1]);
5401       if (TARGET_STFIWX)
5402         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5403       else
5404         {
5405           rtx tmp = gen_reg_rtx (DImode);
5406           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5407           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5408                                                       tmp, stack));
5409         }
5410       DONE;
5411     }
5414 ; Like the convert to float patterns, this insn must be split before
5415 ; register allocation so that it can allocate the memory slot if it
5416 ; needed
5417 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5418   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5419         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5420    (clobber (match_scratch:DI 2 "=d"))]
5421   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5422    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5423    && TARGET_STFIWX && can_create_pseudo_p ()"
5424   "#"
5425   ""
5426   [(pc)]
5428   rtx dest = operands[0];
5429   rtx src = operands[1];
5430   rtx tmp = operands[2];
5432   if (GET_CODE (tmp) == SCRATCH)
5433     tmp = gen_reg_rtx (DImode);
5435   emit_insn (gen_fctiwz_<mode> (tmp, src));
5436   if (MEM_P (dest))
5437     {
5438       dest = rs6000_address_for_fpconvert (dest);
5439       emit_insn (gen_stfiwx (dest, tmp));
5440       DONE;
5441     }
5442   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5443     {
5444       dest = gen_lowpart (DImode, dest);
5445       emit_move_insn (dest, tmp);
5446       DONE;
5447     }
5448   else
5449     {
5450       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5451       emit_insn (gen_stfiwx (stack, tmp));
5452       emit_move_insn (dest, stack);
5453       DONE;
5454     }
5456   [(set_attr "length" "12")
5457    (set_attr "type" "fp")])
5459 (define_insn_and_split "fix_trunc<mode>si2_internal"
5460   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5461         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5462    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5463    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5464   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5465   "#"
5466   ""
5467   [(pc)]
5468   "
5470   rtx lowword;
5471   gcc_assert (MEM_P (operands[3]));
5472   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5474   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5475   emit_move_insn (operands[3], operands[2]);
5476   emit_move_insn (operands[0], lowword);
5477   DONE;
5479   [(set_attr "length" "16")
5480    (set_attr "type" "fp")])
5482 (define_expand "fix_trunc<mode>di2"
5483   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5484         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5485   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5486    && TARGET_FCFID"
5487   "")
5489 (define_insn "*fix_trunc<mode>di2_fctidz"
5490   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5491         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5492   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5493     && TARGET_FCFID"
5494   "@
5495    fctidz %0,%1
5496    xscvdpsxds %x0,%x1"
5497   [(set_attr "type" "fp")])
5499 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5500   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5501    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5502   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5504   rtx op0 = operands[0];
5505   rtx op1 = operands[1];
5506   rtx di_tmp = gen_reg_rtx (DImode);
5508   if (MEM_P (op0))
5509     op0 = rs6000_address_for_fpconvert (op0);
5511   emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5512   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5513   DONE;
5516 (define_expand "fixuns_trunc<mode>si2"
5517   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5518         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5519   "TARGET_HARD_FLOAT
5520    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5521        || <E500_CONVERT>)"
5522   "
5524   if (!<E500_CONVERT>)
5525     {
5526       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5527       DONE;
5528     }
5531 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5532   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5533         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5534    (clobber (match_scratch:DI 2 "=d"))]
5535   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5536    && TARGET_STFIWX && can_create_pseudo_p ()"
5537   "#"
5538   ""
5539   [(pc)]
5541   rtx dest = operands[0];
5542   rtx src = operands[1];
5543   rtx tmp = operands[2];
5545   if (GET_CODE (tmp) == SCRATCH)
5546     tmp = gen_reg_rtx (DImode);
5548   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5549   if (MEM_P (dest))
5550     {
5551       dest = rs6000_address_for_fpconvert (dest);
5552       emit_insn (gen_stfiwx (dest, tmp));
5553       DONE;
5554     }
5555   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5556     {
5557       dest = gen_lowpart (DImode, dest);
5558       emit_move_insn (dest, tmp);
5559       DONE;
5560     }
5561   else
5562     {
5563       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5564       emit_insn (gen_stfiwx (stack, tmp));
5565       emit_move_insn (dest, stack);
5566       DONE;
5567     }
5569   [(set_attr "length" "12")
5570    (set_attr "type" "fp")])
5572 (define_expand "fixuns_trunc<mode>di2"
5573   [(set (match_operand:DI 0 "register_operand" "")
5574         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5575   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5576   "")
5578 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5579   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5580         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5581   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5582     && TARGET_FCTIDUZ"
5583   "@
5584    fctiduz %0,%1
5585    xscvdpuxds %x0,%x1"
5586   [(set_attr "type" "fp")])
5588 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5589   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5590    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5591   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5593   rtx op0 = operands[0];
5594   rtx op1 = operands[1];
5595   rtx di_tmp = gen_reg_rtx (DImode);
5597   if (MEM_P (op0))
5598     op0 = rs6000_address_for_fpconvert (op0);
5600   emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5601   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5602   DONE;
5605 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5606 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5607 ; because the first makes it clear that operand 0 is not live
5608 ; before the instruction.
5609 (define_insn "fctiwz_<mode>"
5610   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5611         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5612                    UNSPEC_FCTIWZ))]
5613   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5614   "@
5615    fctiwz %0,%1
5616    xscvdpsxws %x0,%x1"
5617   [(set_attr "type" "fp")])
5619 (define_insn "fctiwuz_<mode>"
5620   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5621         (unspec:DI [(unsigned_fix:SI
5622                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5623                    UNSPEC_FCTIWUZ))]
5624   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5625   "@
5626    fctiwuz %0,%1
5627    xscvdpuxws %x0,%x1"
5628   [(set_attr "type" "fp")])
5630 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5631 ;; since the friz instruction does not truncate the value if the floating
5632 ;; point value is < LONG_MIN or > LONG_MAX.
5633 (define_insn "*friz"
5634   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5635         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5636   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5637    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5638   "@
5639    friz %0,%1
5640    xsrdpiz %x0,%x1"
5641   [(set_attr "type" "fp")])
5643 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5644 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5645 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5646 ;; extend it, store it back on the stack from the GPR, load it back into the
5647 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5648 ;; disable using store and load to sign/zero extend the value.
5649 (define_insn_and_split "*round32<mode>2_fprs"
5650   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5651         (float:SFDF
5652          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5653    (clobber (match_scratch:DI 2 "=d"))
5654    (clobber (match_scratch:DI 3 "=d"))]
5655   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5656    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5657    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5658   "#"
5659   ""
5660   [(pc)]
5662   rtx dest = operands[0];
5663   rtx src = operands[1];
5664   rtx tmp1 = operands[2];
5665   rtx tmp2 = operands[3];
5666   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5668   if (GET_CODE (tmp1) == SCRATCH)
5669     tmp1 = gen_reg_rtx (DImode);
5670   if (GET_CODE (tmp2) == SCRATCH)
5671     tmp2 = gen_reg_rtx (DImode);
5673   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5674   emit_insn (gen_stfiwx (stack, tmp1));
5675   emit_insn (gen_lfiwax (tmp2, stack));
5676   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5677   DONE;
5679   [(set_attr "type" "fpload")
5680    (set_attr "length" "16")])
5682 (define_insn_and_split "*roundu32<mode>2_fprs"
5683   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5684         (unsigned_float:SFDF
5685          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5686    (clobber (match_scratch:DI 2 "=d"))
5687    (clobber (match_scratch:DI 3 "=d"))]
5688   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5689    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5690    && can_create_pseudo_p ()"
5691   "#"
5692   ""
5693   [(pc)]
5695   rtx dest = operands[0];
5696   rtx src = operands[1];
5697   rtx tmp1 = operands[2];
5698   rtx tmp2 = operands[3];
5699   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5701   if (GET_CODE (tmp1) == SCRATCH)
5702     tmp1 = gen_reg_rtx (DImode);
5703   if (GET_CODE (tmp2) == SCRATCH)
5704     tmp2 = gen_reg_rtx (DImode);
5706   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5707   emit_insn (gen_stfiwx (stack, tmp1));
5708   emit_insn (gen_lfiwzx (tmp2, stack));
5709   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5710   DONE;
5712   [(set_attr "type" "fpload")
5713    (set_attr "length" "16")])
5715 ;; No VSX equivalent to fctid
5716 (define_insn "lrint<mode>di2"
5717   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5718         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5719                    UNSPEC_FCTID))]
5720   "TARGET_<MODE>_FPR && TARGET_FPRND"
5721   "fctid %0,%1"
5722   [(set_attr "type" "fp")])
5724 (define_insn "btrunc<mode>2"
5725   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5726         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5727                      UNSPEC_FRIZ))]
5728   "TARGET_<MODE>_FPR && TARGET_FPRND"
5729   "@
5730    friz %0,%1
5731    xsrdpiz %x0,%x1"
5732   [(set_attr "type" "fp")
5733    (set_attr "fp_type" "fp_addsub_<Fs>")])
5735 (define_insn "ceil<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_FRIP))]
5739   "TARGET_<MODE>_FPR && TARGET_FPRND"
5740   "@
5741    frip %0,%1
5742    xsrdpip %x0,%x1"
5743   [(set_attr "type" "fp")
5744    (set_attr "fp_type" "fp_addsub_<Fs>")])
5746 (define_insn "floor<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_FRIM))]
5750   "TARGET_<MODE>_FPR && TARGET_FPRND"
5751   "@
5752    frim %0,%1
5753    xsrdpim %x0,%x1"
5754   [(set_attr "type" "fp")
5755    (set_attr "fp_type" "fp_addsub_<Fs>")])
5757 ;; No VSX equivalent to frin
5758 (define_insn "round<mode>2"
5759   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5760         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5761                      UNSPEC_FRIN))]
5762   "TARGET_<MODE>_FPR && TARGET_FPRND"
5763   "frin %0,%1"
5764   [(set_attr "type" "fp")
5765    (set_attr "fp_type" "fp_addsub_<Fs>")])
5767 (define_insn "*xsrdpi<mode>2"
5768   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5769         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5770                      UNSPEC_XSRDPI))]
5771   "TARGET_<MODE>_FPR && TARGET_VSX"
5772   "xsrdpi %x0,%x1"
5773   [(set_attr "type" "fp")
5774    (set_attr "fp_type" "fp_addsub_<Fs>")])
5776 (define_expand "lround<mode>di2"
5777   [(set (match_dup 2)
5778         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5779                      UNSPEC_XSRDPI))
5780    (set (match_operand:DI 0 "gpc_reg_operand" "")
5781         (unspec:DI [(match_dup 2)]
5782                    UNSPEC_FCTID))]
5783   "TARGET_<MODE>_FPR && TARGET_VSX"
5785   operands[2] = gen_reg_rtx (<MODE>mode);
5788 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5789 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5790 ; is only generated for Power8 or later.
5791 (define_insn "stfiwx"
5792   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5793         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5794                    UNSPEC_STFIWX))]
5795   "TARGET_PPC_GFXOPT"
5796   "@
5797    stfiwx %1,%y0
5798    stxsiwx %x1,%y0"
5799   [(set_attr "type" "fpstore")])
5801 ;; If we don't have a direct conversion to single precision, don't enable this
5802 ;; conversion for 32-bit without fast math, because we don't have the insn to
5803 ;; generate the fixup swizzle to avoid double rounding problems.
5804 (define_expand "floatsisf2"
5805   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5806         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5807   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5808    && (!TARGET_FPRS
5809        || (TARGET_FPRS
5810            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5811                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5812                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5813   "
5815   if (!TARGET_FPRS)
5816     {
5817       if (!REG_P (operands[1]))
5818         operands[1] = force_reg (SImode, operands[1]);
5819     }
5820   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5821     {
5822       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5823       DONE;
5824     }
5825   else if (TARGET_FCFID && TARGET_LFIWAX)
5826     {
5827       rtx dfreg = gen_reg_rtx (DFmode);
5828       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5829       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5830       DONE;
5831     }
5832   else
5833     {
5834       rtx dreg = operands[1];
5835       if (!REG_P (dreg))
5836         dreg = force_reg (SImode, dreg);
5837       dreg = convert_to_mode (DImode, dreg, false);
5838       emit_insn (gen_floatdisf2 (operands[0], dreg));
5839       DONE;
5840     }
5843 (define_expand "floatdidf2"
5844   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5845         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5846   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5847   "")
5849 (define_insn "*floatdidf2_fpr"
5850   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5851         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5852   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5853   "@
5854    fcfid %0,%1
5855    xscvsxddp %x0,%x1"
5856   [(set_attr "type" "fp")])
5858 ; Allow the combiner to merge source memory operands to the conversion so that
5859 ; the optimizer/register allocator doesn't try to load the value too early in a
5860 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5861 ; hit.  We will split after reload to avoid the trip through the GPRs
5863 (define_insn_and_split "*floatdidf2_mem"
5864   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5865         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5866    (clobber (match_scratch:DI 2 "=d,wi"))]
5867   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5868   "#"
5869   "&& reload_completed"
5870   [(set (match_dup 2) (match_dup 1))
5871    (set (match_dup 0) (float:DF (match_dup 2)))]
5872   ""
5873   [(set_attr "length" "8")
5874    (set_attr "type" "fpload")])
5876 (define_expand "floatunsdidf2"
5877   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5878         (unsigned_float:DF
5879          (match_operand:DI 1 "gpc_reg_operand" "")))]
5880   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5881   "")
5883 (define_insn "*floatunsdidf2_fcfidu"
5884   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5885         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5886   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5887   "@
5888    fcfidu %0,%1
5889    xscvuxddp %x0,%x1"
5890   [(set_attr "type" "fp")
5891    (set_attr "length" "4")])
5893 (define_insn_and_split "*floatunsdidf2_mem"
5894   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5895         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5896    (clobber (match_scratch:DI 2 "=d,wi"))]
5897   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5898   "#"
5899   "&& reload_completed"
5900   [(set (match_dup 2) (match_dup 1))
5901    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5902   ""
5903   [(set_attr "length" "8")
5904    (set_attr "type" "fpload")])
5906 (define_expand "floatdisf2"
5907   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5908         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5909   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5910    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5911   "
5913   if (!TARGET_FCFIDS)
5914     {
5915       rtx val = operands[1];
5916       if (!flag_unsafe_math_optimizations)
5917         {
5918           rtx label = gen_label_rtx ();
5919           val = gen_reg_rtx (DImode);
5920           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5921           emit_label (label);
5922         }
5923       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5924       DONE;
5925     }
5928 (define_insn "floatdisf2_fcfids"
5929   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5930         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5931   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5932    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5933   "@
5934    fcfids %0,%1
5935    xscvsxdsp %x0,%x1"
5936   [(set_attr "type" "fp")])
5938 (define_insn_and_split "*floatdisf2_mem"
5939   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5940         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5941    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5942   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5943    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5944   "#"
5945   "&& reload_completed"
5946   [(pc)]
5947   "
5949   emit_move_insn (operands[2], operands[1]);
5950   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5951   DONE;
5953   [(set_attr "length" "8")])
5955 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5956 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5957 ;; from double rounding.
5958 ;; Instead of creating a new cpu type for two FP operations, just use fp
5959 (define_insn_and_split "floatdisf2_internal1"
5960   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5961         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5962    (clobber (match_scratch:DF 2 "=d"))]
5963   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5964    && !TARGET_FCFIDS"
5965   "#"
5966   "&& reload_completed"
5967   [(set (match_dup 2)
5968         (float:DF (match_dup 1)))
5969    (set (match_dup 0)
5970         (float_truncate:SF (match_dup 2)))]
5971   ""
5972   [(set_attr "length" "8")
5973    (set_attr "type" "fp")])
5975 ;; Twiddles bits to avoid double rounding.
5976 ;; Bits that might be truncated when converting to DFmode are replaced
5977 ;; by a bit that won't be lost at that stage, but is below the SFmode
5978 ;; rounding position.
5979 (define_expand "floatdisf2_internal2"
5980   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5981                                               (const_int 53)))
5982               (clobber (reg:DI CA_REGNO))])
5983    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5984                                            (const_int 2047)))
5985    (set (match_dup 3) (plus:DI (match_dup 3)
5986                                (const_int 1)))
5987    (set (match_dup 0) (plus:DI (match_dup 0)
5988                                (const_int 2047)))
5989    (set (match_dup 4) (compare:CCUNS (match_dup 3)
5990                                      (const_int 2)))
5991    (set (match_dup 0) (ior:DI (match_dup 0)
5992                               (match_dup 1)))
5993    (set (match_dup 0) (and:DI (match_dup 0)
5994                               (const_int -2048)))
5995    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5996                            (label_ref (match_operand:DI 2 "" ""))
5997                            (pc)))
5998    (set (match_dup 0) (match_dup 1))]
5999   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6000    && !TARGET_FCFIDS"
6001   "
6003   operands[3] = gen_reg_rtx (DImode);
6004   operands[4] = gen_reg_rtx (CCUNSmode);
6007 (define_expand "floatunsdisf2"
6008   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6009         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6010   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6011    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6012   "")
6014 (define_insn "floatunsdisf2_fcfidus"
6015   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6016         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6017   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6018    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6019   "@
6020    fcfidus %0,%1
6021    xscvuxdsp %x0,%x1"
6022   [(set_attr "type" "fp")])
6024 (define_insn_and_split "*floatunsdisf2_mem"
6025   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6026         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6027    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6028   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6029    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6030   "#"
6031   "&& reload_completed"
6032   [(pc)]
6033   "
6035   emit_move_insn (operands[2], operands[1]);
6036   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6037   DONE;
6039   [(set_attr "length" "8")
6040    (set_attr "type" "fpload")])
6042 ;; Define the TImode operations that can be done in a small number
6043 ;; of instructions.  The & constraints are to prevent the register
6044 ;; allocator from allocating registers that overlap with the inputs
6045 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6046 ;; also allow for the output being the same as one of the inputs.
6048 (define_expand "addti3"
6049   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6050         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6051                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6052   "TARGET_64BIT"
6054   rtx lo0 = gen_lowpart (DImode, operands[0]);
6055   rtx lo1 = gen_lowpart (DImode, operands[1]);
6056   rtx lo2 = gen_lowpart (DImode, operands[2]);
6057   rtx hi0 = gen_highpart (DImode, operands[0]);
6058   rtx hi1 = gen_highpart (DImode, operands[1]);
6059   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6061   if (!reg_or_short_operand (lo2, DImode))
6062     lo2 = force_reg (DImode, lo2);
6063   if (!adde_operand (hi2, DImode))
6064     hi2 = force_reg (DImode, hi2);
6066   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6067   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6068   DONE;
6071 (define_expand "subti3"
6072   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6073         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6074                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6075   "TARGET_64BIT"
6077   rtx lo0 = gen_lowpart (DImode, operands[0]);
6078   rtx lo1 = gen_lowpart (DImode, operands[1]);
6079   rtx lo2 = gen_lowpart (DImode, operands[2]);
6080   rtx hi0 = gen_highpart (DImode, operands[0]);
6081   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6082   rtx hi2 = gen_highpart (DImode, operands[2]);
6084   if (!reg_or_short_operand (lo1, DImode))
6085     lo1 = force_reg (DImode, lo1);
6086   if (!adde_operand (hi1, DImode))
6087     hi1 = force_reg (DImode, hi1);
6089   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6090   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6091   DONE;
6094 ;; 128-bit logical operations expanders
6096 (define_expand "and<mode>3"
6097   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6098         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6099                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6100   ""
6101   "")
6103 (define_expand "ior<mode>3"
6104   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6105         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6106                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6107   ""
6108   "")
6110 (define_expand "xor<mode>3"
6111   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6112         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6113                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6114   ""
6115   "")
6117 (define_expand "one_cmpl<mode>2"
6118   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6119         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6120   ""
6121   "")
6123 (define_expand "nor<mode>3"
6124   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6125         (and:BOOL_128
6126          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6127          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6128   ""
6129   "")
6131 (define_expand "andc<mode>3"
6132   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6133         (and:BOOL_128
6134          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6135          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6136   ""
6137   "")
6139 ;; Power8 vector logical instructions.
6140 (define_expand "eqv<mode>3"
6141   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6142         (not:BOOL_128
6143          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6144                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6145   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6146   "")
6148 ;; Rewrite nand into canonical form
6149 (define_expand "nand<mode>3"
6150   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6151         (ior:BOOL_128
6152          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6153          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6154   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6155   "")
6157 ;; The canonical form is to have the negated element first, so we need to
6158 ;; reverse arguments.
6159 (define_expand "orc<mode>3"
6160   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6161         (ior:BOOL_128
6162          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6163          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6164   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6165   "")
6167 ;; 128-bit logical operations insns and split operations
6168 (define_insn_and_split "*and<mode>3_internal"
6169   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6170         (and:BOOL_128
6171          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6172          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6173   ""
6175   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6176     return "xxland %x0,%x1,%x2";
6178   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6179     return "vand %0,%1,%2";
6181   return "#";
6183   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6184   [(const_int 0)]
6186   rs6000_split_logical (operands, AND, false, false, false);
6187   DONE;
6189   [(set (attr "type")
6190       (if_then_else
6191         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6192         (const_string "veclogical")
6193         (const_string "integer")))
6194    (set (attr "length")
6195       (if_then_else
6196         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6197         (const_string "4")
6198         (if_then_else
6199          (match_test "TARGET_POWERPC64")
6200          (const_string "8")
6201          (const_string "16"))))])
6203 ;; 128-bit IOR/XOR
6204 (define_insn_and_split "*bool<mode>3_internal"
6205   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6206         (match_operator:BOOL_128 3 "boolean_or_operator"
6207          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6208           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6209   ""
6211   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6212     return "xxl%q3 %x0,%x1,%x2";
6214   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6215     return "v%q3 %0,%1,%2";
6217   return "#";
6219   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6220   [(const_int 0)]
6222   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6223   DONE;
6225   [(set (attr "type")
6226       (if_then_else
6227         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6228         (const_string "veclogical")
6229         (const_string "integer")))
6230    (set (attr "length")
6231       (if_then_else
6232         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6233         (const_string "4")
6234         (if_then_else
6235          (match_test "TARGET_POWERPC64")
6236          (const_string "8")
6237          (const_string "16"))))])
6239 ;; 128-bit ANDC/ORC
6240 (define_insn_and_split "*boolc<mode>3_internal1"
6241   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6242         (match_operator:BOOL_128 3 "boolean_operator"
6243          [(not:BOOL_128
6244            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6245           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6246   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6248   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6249     return "xxl%q3 %x0,%x1,%x2";
6251   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6252     return "v%q3 %0,%1,%2";
6254   return "#";
6256   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6257    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6258   [(const_int 0)]
6260   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6261   DONE;
6263   [(set (attr "type")
6264       (if_then_else
6265         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6266         (const_string "veclogical")
6267         (const_string "integer")))
6268    (set (attr "length")
6269       (if_then_else
6270         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6271         (const_string "4")
6272         (if_then_else
6273          (match_test "TARGET_POWERPC64")
6274          (const_string "8")
6275          (const_string "16"))))])
6277 (define_insn_and_split "*boolc<mode>3_internal2"
6278   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6279         (match_operator:TI2 3 "boolean_operator"
6280          [(not:TI2
6281            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6282           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6283   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6284   "#"
6285   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6286   [(const_int 0)]
6288   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6289   DONE;
6291   [(set_attr "type" "integer")
6292    (set (attr "length")
6293         (if_then_else
6294          (match_test "TARGET_POWERPC64")
6295          (const_string "8")
6296          (const_string "16")))])
6298 ;; 128-bit NAND/NOR
6299 (define_insn_and_split "*boolcc<mode>3_internal1"
6300   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6301         (match_operator:BOOL_128 3 "boolean_operator"
6302          [(not:BOOL_128
6303            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6304           (not:BOOL_128
6305            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6306   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6308   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6309     return "xxl%q3 %x0,%x1,%x2";
6311   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6312     return "v%q3 %0,%1,%2";
6314   return "#";
6316   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6317    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6318   [(const_int 0)]
6320   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6321   DONE;
6323   [(set (attr "type")
6324       (if_then_else
6325         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6326         (const_string "veclogical")
6327         (const_string "integer")))
6328    (set (attr "length")
6329       (if_then_else
6330         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6331         (const_string "4")
6332         (if_then_else
6333          (match_test "TARGET_POWERPC64")
6334          (const_string "8")
6335          (const_string "16"))))])
6337 (define_insn_and_split "*boolcc<mode>3_internal2"
6338   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6339         (match_operator:TI2 3 "boolean_operator"
6340          [(not:TI2
6341            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6342           (not:TI2
6343            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6344   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6345   "#"
6346   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6347   [(const_int 0)]
6349   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6350   DONE;
6352   [(set_attr "type" "integer")
6353    (set (attr "length")
6354         (if_then_else
6355          (match_test "TARGET_POWERPC64")
6356          (const_string "8")
6357          (const_string "16")))])
6360 ;; 128-bit EQV
6361 (define_insn_and_split "*eqv<mode>3_internal1"
6362   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6363         (not:BOOL_128
6364          (xor:BOOL_128
6365           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6366           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6367   "TARGET_P8_VECTOR"
6369   if (vsx_register_operand (operands[0], <MODE>mode))
6370     return "xxleqv %x0,%x1,%x2";
6372   return "#";
6374   "TARGET_P8_VECTOR && reload_completed
6375    && int_reg_operand (operands[0], <MODE>mode)"
6376   [(const_int 0)]
6378   rs6000_split_logical (operands, XOR, true, false, false);
6379   DONE;
6381   [(set (attr "type")
6382       (if_then_else
6383         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6384         (const_string "veclogical")
6385         (const_string "integer")))
6386    (set (attr "length")
6387       (if_then_else
6388         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6389         (const_string "4")
6390         (if_then_else
6391          (match_test "TARGET_POWERPC64")
6392          (const_string "8")
6393          (const_string "16"))))])
6395 (define_insn_and_split "*eqv<mode>3_internal2"
6396   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6397         (not:TI2
6398          (xor:TI2
6399           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6400           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6401   "!TARGET_P8_VECTOR"
6402   "#"
6403   "reload_completed && !TARGET_P8_VECTOR"
6404   [(const_int 0)]
6406   rs6000_split_logical (operands, XOR, true, false, false);
6407   DONE;
6409   [(set_attr "type" "integer")
6410    (set (attr "length")
6411         (if_then_else
6412          (match_test "TARGET_POWERPC64")
6413          (const_string "8")
6414          (const_string "16")))])
6416 ;; 128-bit one's complement
6417 (define_insn_and_split "*one_cmpl<mode>3_internal"
6418   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6419         (not:BOOL_128
6420           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6421   ""
6423   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6424     return "xxlnor %x0,%x1,%x1";
6426   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6427     return "vnor %0,%1,%1";
6429   return "#";
6431   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6432   [(const_int 0)]
6434   rs6000_split_logical (operands, NOT, false, false, false);
6435   DONE;
6437   [(set (attr "type")
6438       (if_then_else
6439         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6440         (const_string "veclogical")
6441         (const_string "integer")))
6442    (set (attr "length")
6443       (if_then_else
6444         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6445         (const_string "4")
6446         (if_then_else
6447          (match_test "TARGET_POWERPC64")
6448          (const_string "8")
6449          (const_string "16"))))])
6452 ;; Now define ways of moving data around.
6454 ;; Set up a register with a value from the GOT table
6456 (define_expand "movsi_got"
6457   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6458         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6459                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6460   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6461   "
6463   if (GET_CODE (operands[1]) == CONST)
6464     {
6465       rtx offset = const0_rtx;
6466       HOST_WIDE_INT value;
6468       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6469       value = INTVAL (offset);
6470       if (value != 0)
6471         {
6472           rtx tmp = (!can_create_pseudo_p ()
6473                      ? operands[0]
6474                      : gen_reg_rtx (Pmode));
6475           emit_insn (gen_movsi_got (tmp, operands[1]));
6476           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6477           DONE;
6478         }
6479     }
6481   operands[2] = rs6000_got_register (operands[1]);
6484 (define_insn "*movsi_got_internal"
6485   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6486         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6487                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6488                    UNSPEC_MOVSI_GOT))]
6489   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6490   "lwz %0,%a1@got(%2)"
6491   [(set_attr "type" "load")])
6493 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6494 ;; didn't get allocated to a hard register.
6495 (define_split
6496   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6497         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6498                     (match_operand:SI 2 "memory_operand" "")]
6499                    UNSPEC_MOVSI_GOT))]
6500   "DEFAULT_ABI == ABI_V4
6501     && flag_pic == 1
6502     && (reload_in_progress || reload_completed)"
6503   [(set (match_dup 0) (match_dup 2))
6504    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6505                                  UNSPEC_MOVSI_GOT))]
6506   "")
6508 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6509 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6510 ;; and this is even supposed to be faster, but it is simpler not to get
6511 ;; integers in the TOC.
6512 (define_insn "movsi_low"
6513   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6514         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6515                            (match_operand 2 "" ""))))]
6516   "TARGET_MACHO && ! TARGET_64BIT"
6517   "lwz %0,lo16(%2)(%1)"
6518   [(set_attr "type" "load")
6519    (set_attr "length" "4")])
6521 (define_insn "*movsi_internal1"
6522   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6523         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6524   "!TARGET_SINGLE_FPU &&
6525    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6526   "@
6527    mr %0,%1
6528    la %0,%a1
6529    lwz%U1%X1 %0,%1
6530    stw%U0%X0 %1,%0
6531    li %0,%1
6532    lis %0,%v1
6533    #
6534    mf%1 %0
6535    mt%0 %1
6536    mt%0 %1
6537    nop"
6538   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6539    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6541 (define_insn "*movsi_internal1_single"
6542   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6543         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6544   "TARGET_SINGLE_FPU &&
6545    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6546   "@
6547    mr %0,%1
6548    la %0,%a1
6549    lwz%U1%X1 %0,%1
6550    stw%U0%X0 %1,%0
6551    li %0,%1
6552    lis %0,%v1
6553    #
6554    mf%1 %0
6555    mt%0 %1
6556    mt%0 %1
6557    nop
6558    stfs%U0%X0 %1,%0
6559    lfs%U1%X1 %0,%1"
6560   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6561    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6563 ;; Split a load of a large constant into the appropriate two-insn
6564 ;; sequence.
6566 (define_split
6567   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6568         (match_operand:SI 1 "const_int_operand" ""))]
6569   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6570    && (INTVAL (operands[1]) & 0xffff) != 0"
6571   [(set (match_dup 0)
6572         (match_dup 2))
6573    (set (match_dup 0)
6574         (ior:SI (match_dup 0)
6575                 (match_dup 3)))]
6576   "
6578   if (rs6000_emit_set_const (operands[0], operands[1]))
6579     DONE;
6580   else
6581     FAIL;
6584 (define_insn "*mov<mode>_internal2"
6585   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6586         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6587                     (const_int 0)))
6588    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6589   ""
6590   "@
6591    cmp<wd>i %2,%0,0
6592    mr. %0,%1
6593    #"
6594   [(set_attr "type" "cmp,logical,cmp")
6595    (set_attr "dot" "yes")
6596    (set_attr "length" "4,4,8")])
6598 (define_split
6599   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6600         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6601                     (const_int 0)))
6602    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6603   "reload_completed"
6604   [(set (match_dup 0) (match_dup 1))
6605    (set (match_dup 2)
6606         (compare:CC (match_dup 0)
6607                     (const_int 0)))]
6608   "")
6610 (define_insn "*movhi_internal"
6611   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6612         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6613   "gpc_reg_operand (operands[0], HImode)
6614    || gpc_reg_operand (operands[1], HImode)"
6615   "@
6616    mr %0,%1
6617    lhz%U1%X1 %0,%1
6618    sth%U0%X0 %1,%0
6619    li %0,%w1
6620    mf%1 %0
6621    mt%0 %1
6622    nop"
6623   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6625 (define_expand "mov<mode>"
6626   [(set (match_operand:INT 0 "general_operand" "")
6627         (match_operand:INT 1 "any_operand" ""))]
6628   ""
6629   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6631 (define_insn "*movqi_internal"
6632   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6633         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6634   "gpc_reg_operand (operands[0], QImode)
6635    || gpc_reg_operand (operands[1], QImode)"
6636   "@
6637    mr %0,%1
6638    lbz%U1%X1 %0,%1
6639    stb%U0%X0 %1,%0
6640    li %0,%1
6641    mf%1 %0
6642    mt%0 %1
6643    nop"
6644   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6646 ;; Here is how to move condition codes around.  When we store CC data in
6647 ;; an integer register or memory, we store just the high-order 4 bits.
6648 ;; This lets us not shift in the most common case of CR0.
6649 (define_expand "movcc"
6650   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6651         (match_operand:CC 1 "nonimmediate_operand" ""))]
6652   ""
6653   "")
6655 (define_insn "*movcc_internal1"
6656   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6657         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6658   "register_operand (operands[0], CCmode)
6659    || register_operand (operands[1], CCmode)"
6660   "@
6661    mcrf %0,%1
6662    mtcrf 128,%1
6663    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6664    crxor %0,%0,%0
6665    mfcr %0%Q1
6666    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6667    mr %0,%1
6668    li %0,%1
6669    mf%1 %0
6670    mt%0 %1
6671    lwz%U1%X1 %0,%1
6672    stw%U0%X0 %1,%0"
6673   [(set (attr "type")
6674      (cond [(eq_attr "alternative" "0,3")
6675                 (const_string "cr_logical")
6676             (eq_attr "alternative" "1,2")
6677                 (const_string "mtcr")
6678             (eq_attr "alternative" "6,7")
6679                 (const_string "integer")
6680             (eq_attr "alternative" "8")
6681                 (const_string "mfjmpr")
6682             (eq_attr "alternative" "9")
6683                 (const_string "mtjmpr")
6684             (eq_attr "alternative" "10")
6685                 (const_string "load")
6686             (eq_attr "alternative" "11")
6687                 (const_string "store")
6688             (match_test "TARGET_MFCRF")
6689                 (const_string "mfcrf")
6690            ]
6691         (const_string "mfcr")))
6692    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6694 ;; For floating-point, we normally deal with the floating-point registers
6695 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6696 ;; can produce floating-point values in fixed-point registers.  Unless the
6697 ;; value is a simple constant or already in memory, we deal with this by
6698 ;; allocating memory and copying the value explicitly via that memory location.
6700 ;; Move 32-bit binary/decimal floating point
6701 (define_expand "mov<mode>"
6702   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6703         (match_operand:FMOVE32 1 "any_operand" ""))]
6704   "<fmove_ok>"
6705   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6707 (define_split
6708   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6709         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6710   "reload_completed
6711    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6712        || (GET_CODE (operands[0]) == SUBREG
6713            && GET_CODE (SUBREG_REG (operands[0])) == REG
6714            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6715   [(set (match_dup 2) (match_dup 3))]
6716   "
6718   long l;
6720   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6722   if (! TARGET_POWERPC64)
6723     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6724   else
6725     operands[2] = gen_lowpart (SImode, operands[0]);
6727   operands[3] = gen_int_mode (l, SImode);
6730 (define_insn "mov<mode>_hardfloat"
6731   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
6732          "=!r,       <f32_lr>,  <f32_lr2>, <f32_av>,  m,         <f32_sm>,
6733           <f32_sm2>, Z,         <f32_vsx>, !r,        ?<f32_dm>, ?r,
6734           f,         <f32_vsx>, !r,        *c*l,      !r,        *h")
6735         (match_operand:FMOVE32 1 "input_operand"
6736          "m,         <f32_lm>,  <f32_lm2>, Z,         r,         <f32_sr>,
6737           <f32_sr2>, <f32_av>,  <zero_fp>, <zero_fp>, r,         <f32_dm>,
6738           f,         <f32_vsx>, r,         r,         *h,        0"))]
6739   "(gpc_reg_operand (operands[0], <MODE>mode)
6740    || gpc_reg_operand (operands[1], <MODE>mode))
6741    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6742   "@
6743    lwz%U1%X1 %0,%1
6744    <f32_li>
6745    <f32_li2>
6746    <f32_lv>
6747    stw%U0%X0 %1,%0
6748    <f32_si>
6749    <f32_si2>
6750    <f32_sv>
6751    xxlxor %x0,%x0,%x0
6752    li %0,0
6753    mtvsrwz %x0,%1
6754    mfvsrwz %0,%x1
6755    fmr %0,%1
6756    xscpsgndp %x0,%x1,%x1
6757    mr %0,%1
6758    mt%0 %1
6759    mf%1 %0
6760    nop"
6761   [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
6763 (define_insn "*mov<mode>_softfloat"
6764   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6765         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6766   "(gpc_reg_operand (operands[0], <MODE>mode)
6767    || gpc_reg_operand (operands[1], <MODE>mode))
6768    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6769   "@
6770    mr %0,%1
6771    mt%0 %1
6772    mf%1 %0
6773    lwz%U1%X1 %0,%1
6774    stw%U0%X0 %1,%0
6775    li %0,%1
6776    lis %0,%v1
6777    #
6778    #
6779    nop"
6780   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6781    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6784 ;; Move 64-bit binary/decimal floating point
6785 (define_expand "mov<mode>"
6786   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6787         (match_operand:FMOVE64 1 "any_operand" ""))]
6788   ""
6789   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6791 (define_split
6792   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6793         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6794   "! TARGET_POWERPC64 && reload_completed
6795    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6796        || (GET_CODE (operands[0]) == SUBREG
6797            && GET_CODE (SUBREG_REG (operands[0])) == REG
6798            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6799   [(set (match_dup 2) (match_dup 4))
6800    (set (match_dup 3) (match_dup 1))]
6801   "
6803   int endian = (WORDS_BIG_ENDIAN == 0);
6804   HOST_WIDE_INT value = INTVAL (operands[1]);
6806   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6807   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6808   operands[4] = GEN_INT (value >> 32);
6809   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6812 (define_split
6813   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6814         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6815   "! TARGET_POWERPC64 && reload_completed
6816    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6817        || (GET_CODE (operands[0]) == SUBREG
6818            && GET_CODE (SUBREG_REG (operands[0])) == REG
6819            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6820   [(set (match_dup 2) (match_dup 4))
6821    (set (match_dup 3) (match_dup 5))]
6822   "
6824   int endian = (WORDS_BIG_ENDIAN == 0);
6825   long l[2];
6827   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6829   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6830   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6831   operands[4] = gen_int_mode (l[endian], SImode);
6832   operands[5] = gen_int_mode (l[1 - endian], SImode);
6835 (define_split
6836   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6837         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6838   "TARGET_POWERPC64 && reload_completed
6839    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6840        || (GET_CODE (operands[0]) == SUBREG
6841            && GET_CODE (SUBREG_REG (operands[0])) == REG
6842            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6843   [(set (match_dup 2) (match_dup 3))]
6844   "
6846   int endian = (WORDS_BIG_ENDIAN == 0);
6847   long l[2];
6848   HOST_WIDE_INT val;
6850   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6852   operands[2] = gen_lowpart (DImode, operands[0]);
6853   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6854   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6855          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6857   operands[3] = gen_int_mode (val, DImode);
6860 ;; Don't have reload use general registers to load a constant.  It is
6861 ;; less efficient than loading the constant into an FP register, since
6862 ;; it will probably be used there.
6864 ;; The move constraints are ordered to prefer floating point registers before
6865 ;; general purpose registers to avoid doing a store and a load to get the value
6866 ;; into a floating point register when it is needed for a floating point
6867 ;; operation.  Prefer traditional floating point registers over VSX registers,
6868 ;; since the D-form version of the memory instructions does not need a GPR for
6869 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6870 ;; registers.
6872 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6873 ;; except for 0.0 which can be created on VSX with an xor instruction.
6875 (define_insn "*mov<mode>_hardfloat32"
6876   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6877         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6878   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6879    && (gpc_reg_operand (operands[0], <MODE>mode)
6880        || gpc_reg_operand (operands[1], <MODE>mode))"
6881   "@
6882    stfd%U0%X0 %1,%0
6883    lfd%U1%X1 %0,%1
6884    fmr %0,%1
6885    lxsd%U1x %x0,%y1
6886    stxsd%U0x %x1,%y0
6887    lxsd %0,%1
6888    stxsd %1,%0
6889    xxlor %x0,%x1,%x1
6890    xxlxor %x0,%x0,%x0
6891    #
6892    #
6893    #
6894    #"
6895   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6896    (set_attr "size" "64")
6897    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6899 (define_insn "*mov<mode>_softfloat32"
6900   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6901         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6902   "! TARGET_POWERPC64 
6903    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6904        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6905        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6906    && (gpc_reg_operand (operands[0], <MODE>mode)
6907        || gpc_reg_operand (operands[1], <MODE>mode))"
6908   "#"
6909   [(set_attr "type" "store,load,two,*,*,*")
6910    (set_attr "length" "8,8,8,8,12,16")])
6912 ; ld/std require word-aligned displacements -> 'Y' constraint.
6913 ; List Y->r and r->Y before r->r for reload.
6914 (define_insn "*mov<mode>_hardfloat64"
6915   [(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>")
6916         (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"))]
6917   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6918    && (gpc_reg_operand (operands[0], <MODE>mode)
6919        || gpc_reg_operand (operands[1], <MODE>mode))"
6920   "@
6921    stfd%U0%X0 %1,%0
6922    lfd%U1%X1 %0,%1
6923    fmr %0,%1
6924    lxsd %0,%1
6925    stxsd %1,%0
6926    lxsd%U1x %x0,%y1
6927    stxsd%U0x %x1,%y0
6928    xxlor %x0,%x1,%x1
6929    xxlxor %x0,%x0,%x0
6930    li %0,0
6931    std%U0%X0 %1,%0
6932    ld%U1%X1 %0,%1
6933    mr %0,%1
6934    mt%0 %1
6935    mf%1 %0
6936    nop
6937    mftgpr %0,%1
6938    mffgpr %0,%1
6939    mfvsrd %0,%x1
6940    mtvsrd %x0,%1"
6941   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6942    (set_attr "size" "64")
6943    (set_attr "length" "4")])
6945 (define_insn "*mov<mode>_softfloat64"
6946   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6947         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6948   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6949    && (gpc_reg_operand (operands[0], <MODE>mode)
6950        || gpc_reg_operand (operands[1], <MODE>mode))"
6951   "@
6952    std%U0%X0 %1,%0
6953    ld%U1%X1 %0,%1
6954    mr %0,%1
6955    mt%0 %1
6956    mf%1 %0
6957    #
6958    #
6959    #
6960    nop"
6961   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6962    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6964 (define_expand "mov<mode>"
6965   [(set (match_operand:FMOVE128 0 "general_operand" "")
6966         (match_operand:FMOVE128 1 "any_operand" ""))]
6967   ""
6968   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6970 ;; It's important to list Y->r and r->Y before r->r because otherwise
6971 ;; reload, given m->r, will try to pick r->r and reload it, which
6972 ;; doesn't make progress.
6974 ;; We can't split little endian direct moves of TDmode, because the words are
6975 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6976 ;; problematical.  Don't allow direct move for this case.
6978 (define_insn_and_split "*mov<mode>_64bit_dm"
6979   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6980         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6981   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6982    && FLOAT128_2REG_P (<MODE>mode)
6983    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6984    && (gpc_reg_operand (operands[0], <MODE>mode)
6985        || gpc_reg_operand (operands[1], <MODE>mode))"
6986   "#"
6987   "&& reload_completed"
6988   [(pc)]
6989 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6990   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6992 (define_insn_and_split "*movtd_64bit_nodm"
6993   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6994         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6995   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6996    && (gpc_reg_operand (operands[0], TDmode)
6997        || gpc_reg_operand (operands[1], TDmode))"
6998   "#"
6999   "&& reload_completed"
7000   [(pc)]
7001 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7002   [(set_attr "length" "8,8,8,12,12,8")])
7004 (define_insn_and_split "*mov<mode>_32bit"
7005   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7006         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7007   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7008    && (FLOAT128_2REG_P (<MODE>mode)
7009        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7010        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7011    && (gpc_reg_operand (operands[0], <MODE>mode)
7012        || gpc_reg_operand (operands[1], <MODE>mode))"
7013   "#"
7014   "&& reload_completed"
7015   [(pc)]
7016 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7017   [(set_attr "length" "8,8,8,8,20,20,16")])
7019 (define_insn_and_split "*mov<mode>_softfloat"
7020   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7021         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7022   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7023    && (gpc_reg_operand (operands[0], <MODE>mode)
7024        || gpc_reg_operand (operands[1], <MODE>mode))"
7025   "#"
7026   "&& reload_completed"
7027   [(pc)]
7028 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7029   [(set_attr "length" "20,20,16")])
7031 (define_expand "extenddf<mode>2"
7032   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7033         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7034   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7035    && TARGET_LONG_DOUBLE_128"
7037   if (FLOAT128_IEEE_P (<MODE>mode))
7038     rs6000_expand_float128_convert (operands[0], operands[1], false);
7039   else if (TARGET_E500_DOUBLE)
7040     {
7041       gcc_assert (<MODE>mode == TFmode);
7042       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7043     }
7044   else if (TARGET_VSX)
7045     {
7046       if (<MODE>mode == TFmode)
7047         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7048       else if (<MODE>mode == IFmode)
7049         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7050       else
7051         gcc_unreachable ();
7052     }
7053    else
7054     {
7055       rtx zero = gen_reg_rtx (DFmode);
7056       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7058       if (<MODE>mode == TFmode)
7059         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7060       else if (<MODE>mode == IFmode)
7061         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7062       else
7063         gcc_unreachable ();
7064     }
7065   DONE;
7068 ;; Allow memory operands for the source to be created by the combiner.
7069 (define_insn_and_split "extenddf<mode>2_fprs"
7070   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7071         (float_extend:IBM128
7072          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7073    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7074   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7075    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7076   "#"
7077   "&& reload_completed"
7078   [(set (match_dup 3) (match_dup 1))
7079    (set (match_dup 4) (match_dup 2))]
7081   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7082   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7084   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7085   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7088 (define_insn_and_split "extenddf<mode>2_vsx"
7089   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7090         (float_extend:IBM128
7091          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7092   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7093   "#"
7094   "&& reload_completed"
7095   [(set (match_dup 2) (match_dup 1))
7096    (set (match_dup 3) (match_dup 4))]
7098   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7099   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7101   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7102   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7103   operands[4] = CONST0_RTX (DFmode);
7106 (define_expand "extendsf<mode>2"
7107   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7108         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7109   "TARGET_HARD_FLOAT
7110    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7111    && TARGET_LONG_DOUBLE_128"
7113   if (FLOAT128_IEEE_P (<MODE>mode))
7114     rs6000_expand_float128_convert (operands[0], operands[1], false);
7115   else
7116     {
7117       rtx tmp = gen_reg_rtx (DFmode);
7118       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7119       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7120     }
7121   DONE;
7124 (define_expand "trunc<mode>df2"
7125   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7126         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7127   "TARGET_HARD_FLOAT
7128    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7129    && TARGET_LONG_DOUBLE_128"
7131   if (FLOAT128_IEEE_P (<MODE>mode))
7132     {
7133       rs6000_expand_float128_convert (operands[0], operands[1], false);
7134       DONE;
7135     }
7138 (define_insn_and_split "trunc<mode>df2_internal1"
7139   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7140         (float_truncate:DF
7141          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7142   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7143    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7144   "@
7145    #
7146    fmr %0,%1"
7147   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7148   [(const_int 0)]
7150   emit_note (NOTE_INSN_DELETED);
7151   DONE;
7153   [(set_attr "type" "fpsimple")])
7155 (define_insn "trunc<mode>df2_internal2"
7156   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7157         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7158   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7159    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7160   "fadd %0,%1,%L1"
7161   [(set_attr "type" "fp")
7162    (set_attr "fp_type" "fp_addsub_d")])
7164 (define_expand "trunc<mode>sf2"
7165   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7166         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7167   "TARGET_HARD_FLOAT
7168    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7169    && TARGET_LONG_DOUBLE_128"
7171   if (FLOAT128_IEEE_P (<MODE>mode))
7172     rs6000_expand_float128_convert (operands[0], operands[1], false);
7173   else if (TARGET_E500_DOUBLE)
7174     {
7175       gcc_assert (<MODE>mode == TFmode);
7176       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7177     }
7178   else if (<MODE>mode == TFmode)
7179     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7180   else if (<MODE>mode == IFmode)
7181     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7182   else
7183     gcc_unreachable ();
7184   DONE;
7187 (define_insn_and_split "trunc<mode>sf2_fprs"
7188   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7189         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7190    (clobber (match_scratch:DF 2 "=d"))]
7191   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7192    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7193   "#"
7194   "&& reload_completed"
7195   [(set (match_dup 2)
7196         (float_truncate:DF (match_dup 1)))
7197    (set (match_dup 0)
7198         (float_truncate:SF (match_dup 2)))]
7199   "")
7201 (define_expand "floatsi<mode>2"
7202   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7203         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7204   "TARGET_HARD_FLOAT
7205    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7206    && TARGET_LONG_DOUBLE_128"
7208   if (FLOAT128_IEEE_P (<MODE>mode))
7209     rs6000_expand_float128_convert (operands[0], operands[1], false);
7210   else
7211     {
7212       rtx tmp = gen_reg_rtx (DFmode);
7213       expand_float (tmp, operands[1], false);
7214       if (<MODE>mode == TFmode)
7215         emit_insn (gen_extenddftf2 (operands[0], tmp));
7216       else if (<MODE>mode == IFmode)
7217         emit_insn (gen_extenddfif2 (operands[0], tmp));
7218       else
7219         gcc_unreachable ();
7220     }
7221   DONE;
7224 ; fadd, but rounding towards zero.
7225 ; This is probably not the optimal code sequence.
7226 (define_insn "fix_trunc_helper<mode>"
7227   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7228         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7229                    UNSPEC_FIX_TRUNC_TF))
7230    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7231   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7232    && FLOAT128_IBM_P (<MODE>mode)"
7233   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7234   [(set_attr "type" "fp")
7235    (set_attr "length" "20")])
7237 (define_expand "fix_trunc<mode>si2"
7238   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7239         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7240   "TARGET_HARD_FLOAT
7241    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7243   if (FLOAT128_IEEE_P (<MODE>mode))
7244     rs6000_expand_float128_convert (operands[0], operands[1], false);
7245   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7246     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7247   else if (<MODE>mode == TFmode)
7248     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7249   else if (<MODE>mode == IFmode)
7250     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7251   else
7252     gcc_unreachable ();
7253   DONE;
7256 (define_expand "fix_trunc<mode>si2_fprs"
7257   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7258                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7259               (clobber (match_dup 2))
7260               (clobber (match_dup 3))
7261               (clobber (match_dup 4))
7262               (clobber (match_dup 5))])]
7263   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7265   operands[2] = gen_reg_rtx (DFmode);
7266   operands[3] = gen_reg_rtx (DFmode);
7267   operands[4] = gen_reg_rtx (DImode);
7268   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7271 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7272   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7273         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7274    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7275    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7276    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7277    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7278   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7279   "#"
7280   ""
7281   [(pc)]
7283   rtx lowword;
7284   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7285                                          operands[3]));
7287   gcc_assert (MEM_P (operands[5]));
7288   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7290   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7291   emit_move_insn (operands[5], operands[4]);
7292   emit_move_insn (operands[0], lowword);
7293   DONE;
7296 (define_expand "fix_trunc<mode>di2"
7297   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7298         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7299   "TARGET_FLOAT128"
7301   rs6000_expand_float128_convert (operands[0], operands[1], false);
7302   DONE;
7305 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7306   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7307         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7308   "TARGET_FLOAT128"
7310   rs6000_expand_float128_convert (operands[0], operands[1], true);
7311   DONE;
7314 (define_expand "floatdi<mode>2"
7315   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7316         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7317   "TARGET_FLOAT128"
7319   rs6000_expand_float128_convert (operands[0], operands[1], false);
7320   DONE;
7323 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7324   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7325         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7326   "TARGET_FLOAT128"
7328   rs6000_expand_float128_convert (operands[0], operands[1], true);
7329   DONE;
7332 (define_expand "neg<mode>2"
7333   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7334         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7335   "FLOAT128_IEEE_P (<MODE>mode)
7336    || (FLOAT128_IBM_P (<MODE>mode)
7337        && TARGET_HARD_FLOAT
7338        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7339   "
7341   if (FLOAT128_IEEE_P (<MODE>mode))
7342     {
7343       if (TARGET_FLOAT128_HW)
7344         {
7345           if (<MODE>mode == TFmode)
7346             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7347           else if (<MODE>mode == KFmode)
7348             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7349           else
7350             gcc_unreachable ();
7351         }
7352       else if (TARGET_FLOAT128)
7353         {
7354           if (<MODE>mode == TFmode)
7355             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7356           else if (<MODE>mode == KFmode)
7357             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7358           else
7359             gcc_unreachable ();
7360         }
7361       else
7362         {
7363           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7364           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7365                                                 <MODE>mode, 1,
7366                                                 operands[1], <MODE>mode);
7368           if (target && !rtx_equal_p (target, operands[0]))
7369             emit_move_insn (operands[0], target);
7370         }
7371       DONE;
7372     }
7375 (define_insn "neg<mode>2_internal"
7376   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7377         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7378   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7379   "*
7381   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7382     return \"fneg %L0,%L1\;fneg %0,%1\";
7383   else
7384     return \"fneg %0,%1\;fneg %L0,%L1\";
7386   [(set_attr "type" "fpsimple")
7387    (set_attr "length" "8")])
7389 (define_expand "abs<mode>2"
7390   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7391         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7392   "FLOAT128_IEEE_P (<MODE>mode)
7393    || (FLOAT128_IBM_P (<MODE>mode)
7394        && TARGET_HARD_FLOAT
7395        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7396   "
7398   rtx label;
7400   if (FLOAT128_IEEE_P (<MODE>mode))
7401     {
7402       if (TARGET_FLOAT128_HW)
7403         {
7404           if (<MODE>mode == TFmode)
7405             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7406           else if (<MODE>mode == KFmode)
7407             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7408           else
7409             FAIL;
7410           DONE;
7411         }
7412       else if (TARGET_FLOAT128)
7413         {
7414           if (<MODE>mode == TFmode)
7415             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7416           else if (<MODE>mode == KFmode)
7417             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7418           else
7419             FAIL;
7420           DONE;
7421         }
7422       else
7423         FAIL;
7424     }
7426   label = gen_label_rtx ();
7427   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7428     {
7429       if (flag_finite_math_only && !flag_trapping_math)
7430         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7431       else
7432         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7433     }
7434   else if (<MODE>mode == TFmode)
7435     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7436   else if (<MODE>mode == TFmode)
7437     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7438   else
7439     FAIL;
7440   emit_label (label);
7441   DONE;
7444 (define_expand "abs<mode>2_internal"
7445   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7446         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7447    (set (match_dup 3) (match_dup 5))
7448    (set (match_dup 5) (abs:DF (match_dup 5)))
7449    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7450    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7451                            (label_ref (match_operand 2 "" ""))
7452                            (pc)))
7453    (set (match_dup 6) (neg:DF (match_dup 6)))]
7454   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7455    && TARGET_LONG_DOUBLE_128"
7456   "
7458   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7459   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7460   operands[3] = gen_reg_rtx (DFmode);
7461   operands[4] = gen_reg_rtx (CCFPmode);
7462   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7463   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7467 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7468 ;; register
7470 (define_expand "ieee_128bit_negative_zero"
7471   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7472   "TARGET_FLOAT128"
7474   rtvec v = rtvec_alloc (16);
7475   int i, high;
7477   for (i = 0; i < 16; i++)
7478     RTVEC_ELT (v, i) = const0_rtx;
7480   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7481   RTVEC_ELT (v, high) = GEN_INT (0x80);
7483   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7484   DONE;
7487 ;; IEEE 128-bit negate
7489 ;; We have 2 insns here for negate and absolute value.  The first uses
7490 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7491 ;; insns, and second insn after the first split pass loads up the bit to
7492 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7493 ;; neg/abs to create the constant just once.
7495 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7496   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7497         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7498    (clobber (match_scratch:V16QI 2 "=v"))]
7499   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7500   "#"
7501   "&& 1"
7502   [(parallel [(set (match_dup 0)
7503                    (neg:IEEE128 (match_dup 1)))
7504               (use (match_dup 2))])]
7506   if (GET_CODE (operands[2]) == SCRATCH)
7507     operands[2] = gen_reg_rtx (V16QImode);
7509   operands[3] = gen_reg_rtx (V16QImode);
7510   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7512   [(set_attr "length" "8")
7513    (set_attr "type" "vecsimple")])
7515 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7516   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7517         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7518    (use (match_operand:V16QI 2 "register_operand" "v"))]
7519   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7520   "xxlxor %x0,%x1,%x2"
7521   [(set_attr "type" "veclogical")])
7523 ;; IEEE 128-bit absolute value
7524 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7525   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7526         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7527    (clobber (match_scratch:V16QI 2 "=v"))]
7528   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7529   "#"
7530   "&& 1"
7531   [(parallel [(set (match_dup 0)
7532                    (abs:IEEE128 (match_dup 1)))
7533               (use (match_dup 2))])]
7535   if (GET_CODE (operands[2]) == SCRATCH)
7536     operands[2] = gen_reg_rtx (V16QImode);
7538   operands[3] = gen_reg_rtx (V16QImode);
7539   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7541   [(set_attr "length" "8")
7542    (set_attr "type" "vecsimple")])
7544 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7545   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7546         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7547    (use (match_operand:V16QI 2 "register_operand" "v"))]
7548   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7549   "xxlandc %x0,%x1,%x2"
7550   [(set_attr "type" "veclogical")])
7552 ;; IEEE 128-bit negative absolute value
7553 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7554   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7555         (neg:IEEE128
7556          (abs:IEEE128
7557           (match_operand:IEEE128 1 "register_operand" "wa"))))
7558    (clobber (match_scratch:V16QI 2 "=v"))]
7559   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7560   "#"
7561   "&& 1"
7562   [(parallel [(set (match_dup 0)
7563                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7564               (use (match_dup 2))])]
7566   if (GET_CODE (operands[2]) == SCRATCH)
7567     operands[2] = gen_reg_rtx (V16QImode);
7569   operands[3] = gen_reg_rtx (V16QImode);
7570   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7572   [(set_attr "length" "8")
7573    (set_attr "type" "vecsimple")])
7575 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7576   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7577         (neg:IEEE128
7578          (abs:IEEE128
7579           (match_operand:IEEE128 1 "register_operand" "wa"))))
7580    (use (match_operand:V16QI 2 "register_operand" "v"))]
7581   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7582   "xxlor %x0,%x1,%x2"
7583   [(set_attr "type" "veclogical")])
7585 ;; Float128 conversion functions.  These expand to library function calls.
7586 ;; We use expand to convert from IBM double double to IEEE 128-bit
7587 ;; and trunc for the opposite.
7588 (define_expand "extendiftf2"
7589   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7590         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7591   "TARGET_FLOAT128"
7593   rs6000_expand_float128_convert (operands[0], operands[1], false);
7594   DONE;
7597 (define_expand "extendifkf2"
7598   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7599         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7600   "TARGET_FLOAT128"
7602   rs6000_expand_float128_convert (operands[0], operands[1], false);
7603   DONE;
7606 (define_expand "extendtfkf2"
7607   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7608         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7609   "TARGET_FLOAT128"
7611   rs6000_expand_float128_convert (operands[0], operands[1], false);
7612   DONE;
7615 (define_expand "trunciftf2"
7616   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7617         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7618   "TARGET_FLOAT128"
7620   rs6000_expand_float128_convert (operands[0], operands[1], false);
7621   DONE;
7624 (define_expand "truncifkf2"
7625   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7626         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7627   "TARGET_FLOAT128"
7629   rs6000_expand_float128_convert (operands[0], operands[1], false);
7630   DONE;
7633 (define_expand "trunckftf2"
7634   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7635         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7636   "TARGET_FLOAT128"
7638   rs6000_expand_float128_convert (operands[0], operands[1], false);
7639   DONE;
7642 (define_expand "trunctfif2"
7643   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7644         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7645   "TARGET_FLOAT128"
7647   rs6000_expand_float128_convert (operands[0], operands[1], false);
7648   DONE;
7652 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7653 ;; must have 3 arguments, and scratch register constraint must be a single
7654 ;; constraint.
7656 ;; Reload patterns to support gpr load/store with misaligned mem.
7657 ;; and multiple gpr load/store at offset >= 0xfffc
7658 (define_expand "reload_<mode>_store"
7659   [(parallel [(match_operand 0 "memory_operand" "=m")
7660               (match_operand 1 "gpc_reg_operand" "r")
7661               (match_operand:GPR 2 "register_operand" "=&b")])]
7662   ""
7664   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7665   DONE;
7668 (define_expand "reload_<mode>_load"
7669   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7670               (match_operand 1 "memory_operand" "m")
7671               (match_operand:GPR 2 "register_operand" "=b")])]
7672   ""
7674   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7675   DONE;
7679 ;; Reload patterns for various types using the vector registers.  We may need
7680 ;; an additional base register to convert the reg+offset addressing to reg+reg
7681 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7682 ;; index register for gpr registers.
7683 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7684   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7685               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7686               (match_operand:P 2 "register_operand" "=b")])]
7687   "<P:tptrsize>"
7689   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7690   DONE;
7693 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7694   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7695               (match_operand:RELOAD 1 "memory_operand" "m")
7696               (match_operand:P 2 "register_operand" "=b")])]
7697   "<P:tptrsize>"
7699   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7700   DONE;
7704 ;; Reload sometimes tries to move the address to a GPR, and can generate
7705 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7706 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7708 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7709   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7710         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7711                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7712                (const_int -16)))]
7713   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7714   "#"
7715   "&& reload_completed"
7716   [(set (match_dup 0)
7717         (plus:P (match_dup 1)
7718                 (match_dup 2)))
7719    (set (match_dup 0)
7720         (and:P (match_dup 0)
7721                (const_int -16)))])
7723 ;; Power8 merge instructions to allow direct move to/from floating point
7724 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7725 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7726 ;; value, since it is allocated in reload and not all of the flow information
7727 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7728 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7729 ;; schedule other instructions between the two instructions.
7731 (define_insn "p8_fmrgow_<mode>"
7732   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7733         (unspec:FMOVE64X [
7734                 (match_operand:DF 1 "register_operand" "d")
7735                 (match_operand:DF 2 "register_operand" "d")]
7736                          UNSPEC_P8V_FMRGOW))]
7737   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7738   "fmrgow %0,%1,%2"
7739   [(set_attr "type" "fpsimple")])
7741 (define_insn "p8_mtvsrwz"
7742   [(set (match_operand:DF 0 "register_operand" "=d")
7743         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7744                    UNSPEC_P8V_MTVSRWZ))]
7745   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7746   "mtvsrwz %x0,%1"
7747   [(set_attr "type" "mftgpr")])
7749 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7750   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7751         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7752                          UNSPEC_P8V_RELOAD_FROM_GPR))
7753    (clobber (match_operand:IF 2 "register_operand" "=d"))]
7754   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7755   "#"
7756   "&& reload_completed"
7757   [(const_int 0)]
7759   rtx dest = operands[0];
7760   rtx src = operands[1];
7761   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7762   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7763   rtx gpr_hi_reg = gen_highpart (SImode, src);
7764   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7766   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7767   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7768   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7769   DONE;
7771   [(set_attr "length" "12")
7772    (set_attr "type" "three")])
7774 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7775 (define_insn "p8_mtvsrd_df"
7776   [(set (match_operand:DF 0 "register_operand" "=wa")
7777         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7778                    UNSPEC_P8V_MTVSRD))]
7779   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7780   "mtvsrd %x0,%1"
7781   [(set_attr "type" "mftgpr")])
7783 (define_insn "p8_xxpermdi_<mode>"
7784   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7785         (unspec:FMOVE128_GPR [
7786                 (match_operand:DF 1 "register_operand" "wa")
7787                 (match_operand:DF 2 "register_operand" "wa")]
7788                 UNSPEC_P8V_XXPERMDI))]
7789   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7790   "xxpermdi %x0,%x1,%x2,0"
7791   [(set_attr "type" "vecperm")])
7793 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7794   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7795         (unspec:FMOVE128_GPR
7796          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7797          UNSPEC_P8V_RELOAD_FROM_GPR))
7798    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7799   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7800   "#"
7801   "&& reload_completed"
7802   [(const_int 0)]
7804   rtx dest = operands[0];
7805   rtx src = operands[1];
7806   /* You might think that we could use op0 as one temp and a DF clobber
7807      as op2, but you'd be wrong.  Secondary reload move patterns don't
7808      check for overlap of the clobber and the destination.  */
7809   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7810   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7811   rtx gpr_hi_reg = gen_highpart (DImode, src);
7812   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7814   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7815   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7816   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7817   DONE;
7819   [(set_attr "length" "12")
7820    (set_attr "type" "three")])
7822 (define_split
7823   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7824         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7825   "reload_completed
7826    && (int_reg_operand (operands[0], <MODE>mode)
7827        || int_reg_operand (operands[1], <MODE>mode))
7828    && (!TARGET_DIRECT_MOVE_128
7829        || (!vsx_register_operand (operands[0], <MODE>mode)
7830            && !vsx_register_operand (operands[1], <MODE>mode)))"
7831   [(pc)]
7832 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7834 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7835 ;; type is stored internally as double precision in the VSX registers, we have
7836 ;; to convert it from the vector format.
7837 (define_insn "p8_mtvsrd_sf"
7838   [(set (match_operand:SF 0 "register_operand" "=wa")
7839         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7840                    UNSPEC_P8V_MTVSRD))]
7841   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7842   "mtvsrd %x0,%1"
7843   [(set_attr "type" "mftgpr")])
7845 (define_insn_and_split "reload_vsx_from_gprsf"
7846   [(set (match_operand:SF 0 "register_operand" "=wa")
7847         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7848                    UNSPEC_P8V_RELOAD_FROM_GPR))
7849    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7850   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7851   "#"
7852   "&& reload_completed"
7853   [(const_int 0)]
7855   rtx op0 = operands[0];
7856   rtx op1 = operands[1];
7857   rtx op2 = operands[2];
7858   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7860   /* Move SF value to upper 32-bits for xscvspdpn.  */
7861   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7862   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7863   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7864   DONE;
7866   [(set_attr "length" "8")
7867    (set_attr "type" "two")])
7869 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7870 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7871 ;; and then doing a move of that.
7872 (define_insn "p8_mfvsrd_3_<mode>"
7873   [(set (match_operand:DF 0 "register_operand" "=r")
7874         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7875                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7876   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7877   "mfvsrd %0,%x1"
7878   [(set_attr "type" "mftgpr")])
7880 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7881   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7882         (unspec:FMOVE128_GPR
7883          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7884          UNSPEC_P8V_RELOAD_FROM_VSX))
7885    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7886   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7887   "#"
7888   "&& reload_completed"
7889   [(const_int 0)]
7891   rtx dest = operands[0];
7892   rtx src = operands[1];
7893   rtx tmp = operands[2];
7894   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7895   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7897   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7898   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7899   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7900   DONE;
7902   [(set_attr "length" "12")
7903    (set_attr "type" "three")])
7905 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7906 ;; type is stored internally as double precision, we have to convert it to the
7907 ;; vector format.
7909 (define_insn_and_split "reload_gpr_from_vsxsf"
7910   [(set (match_operand:SF 0 "register_operand" "=r")
7911         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7912                    UNSPEC_P8V_RELOAD_FROM_VSX))
7913    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7914   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7915   "#"
7916   "&& reload_completed"
7917   [(const_int 0)]
7919   rtx op0 = operands[0];
7920   rtx op1 = operands[1];
7921   rtx op2 = operands[2];
7922   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7924   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7925   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7926   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7927   DONE;
7929   [(set_attr "length" "12")
7930    (set_attr "type" "three")])
7932 (define_insn "p8_mfvsrd_4_disf"
7933   [(set (match_operand:DI 0 "register_operand" "=r")
7934         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7935                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7936   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7937   "mfvsrd %0,%x1"
7938   [(set_attr "type" "mftgpr")])
7941 ;; Next come the multi-word integer load and store and the load and store
7942 ;; multiple insns.
7944 ;; List r->r after r->Y, otherwise reload will try to reload a
7945 ;; non-offsettable address by using r->r which won't make progress.
7946 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7947 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7949 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
7950 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
7951 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
7952 ;;        AVX const  
7954 (define_insn "*movdi_internal32"
7955   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
7956          "=Y,        r,         r,         ?m,        ?*d,        ?*d,
7957           r,         ?wY,       ?Z,        ?*wb,      ?*wv,       ?wi,
7958           ?wo,       ?wo,       ?wv,       ?wi,       ?wi,        ?wv,
7959           ?wv")
7961         (match_operand:DI 1 "input_operand"
7962           "r,        Y,         r,         d,         m,          d,
7963            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
7964            Oj,       wM,        OjwM,      Oj,        wM,         wS,
7965            wB"))]
7967   "! TARGET_POWERPC64
7968    && (gpc_reg_operand (operands[0], DImode)
7969        || gpc_reg_operand (operands[1], DImode))"
7970   "@
7971    #
7972    #
7973    #
7974    stfd%U0%X0 %1,%0
7975    lfd%U1%X1 %0,%1
7976    fmr %0,%1
7977    #
7978    stxsd %1,%0
7979    stxsdx %x1,%y0
7980    lxsd %0,%1
7981    lxsdx %x0,%y1
7982    xxlor %x0,%x1,%x1
7983    xxspltib %x0,0
7984    xxspltib %x0,255
7985    vspltisw %0,%1
7986    xxlxor %x0,%x0,%x0
7987    xxlorc %x0,%x0,%x0
7988    #
7989    #"
7990   [(set_attr "type"
7991                "store,     load,      *,         fpstore,    fpload,     fpsimple,
7992                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
7993                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
7994                 vecsimple")
7995    (set_attr "size" "64")])
7997 (define_split
7998   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7999         (match_operand:DI 1 "const_int_operand" ""))]
8000   "! TARGET_POWERPC64 && reload_completed
8001    && gpr_or_gpr_p (operands[0], operands[1])
8002    && !direct_move_p (operands[0], operands[1])"
8003   [(set (match_dup 2) (match_dup 4))
8004    (set (match_dup 3) (match_dup 1))]
8005   "
8007   HOST_WIDE_INT value = INTVAL (operands[1]);
8008   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8009                                        DImode);
8010   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8011                                        DImode);
8012   operands[4] = GEN_INT (value >> 32);
8013   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8016 (define_split
8017   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8018         (match_operand:DIFD 1 "input_operand" ""))]
8019   "reload_completed && !TARGET_POWERPC64
8020    && gpr_or_gpr_p (operands[0], operands[1])
8021    && !direct_move_p (operands[0], operands[1])"
8022   [(pc)]
8023 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8025 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8026 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8027 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8028 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8029 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8030 (define_insn "*movdi_internal64"
8031   [(set (match_operand:DI 0 "nonimmediate_operand"
8032                "=Y,        r,         r,         r,         r,          r,
8033                 ?m,        ?*d,       ?*d,       ?wY,       ?Z,         ?*wb,
8034                 ?*wv,      ?wi,       ?wo,       ?wo,       ?wv,        ?wi,
8035                 ?wi,       ?wv,       ?wv,       r,         *h,         *h,
8036                 ?*r,       ?*wg,      ?*r,       ?*wj")
8038         (match_operand:DI 1 "input_operand"
8039                 "r,        Y,         r,         I,         L,          nF,
8040                  d,        m,         d,         wb,        wv,         wY,
8041                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8042                  wM,       wS,        wB,        *h,        r,          0,
8043                  wg,       r,         wj,        r"))]
8045   "TARGET_POWERPC64
8046    && (gpc_reg_operand (operands[0], DImode)
8047        || gpc_reg_operand (operands[1], DImode))"
8048   "@
8049    std%U0%X0 %1,%0
8050    ld%U1%X1 %0,%1
8051    mr %0,%1
8052    li %0,%1
8053    lis %0,%v1
8054    #
8055    stfd%U0%X0 %1,%0
8056    lfd%U1%X1 %0,%1
8057    fmr %0,%1
8058    stxsd %1,%0
8059    stxsdx %x1,%y0
8060    lxsd %0,%1
8061    lxsdx %x0,%y1
8062    xxlor %x0,%x1,%x1
8063    xxspltib %x0,0
8064    xxspltib %x0,255
8065    vspltisw %0,%1
8066    xxlxor %x0,%x0,%x0
8067    xxlorc %x0,%x0,%x0
8068    #
8069    #
8070    mf%1 %0
8071    mt%0 %1
8072    nop
8073    mftgpr %0,%1
8074    mffgpr %0,%1
8075    mfvsrd %0,%x1
8076    mtvsrd %x0,%1"
8077   [(set_attr "type"
8078                "store,      load,       *,         *,         *,         *,
8079                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8080                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8081                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8082                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8084    (set_attr "size" "64")
8085    (set_attr "length"
8086                "4,         4,         4,         4,         4,          20,
8087                 4,         4,         4,         4,         4,          4,
8088                 4,         4,         4,         4,         4,          8,
8089                 8,         4,         4,         4,         4,          4,
8090                 4,         4,         4,         4")])
8092 ; Some DImode loads are best done as a load of -1 followed by a mask
8093 ; instruction.
8094 (define_split
8095   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8096         (match_operand:DI 1 "const_int_operand"))]
8097   "TARGET_POWERPC64
8098    && num_insns_constant (operands[1], DImode) > 1
8099    && rs6000_is_valid_and_mask (operands[1], DImode)"
8100   [(set (match_dup 0)
8101         (const_int -1))
8102    (set (match_dup 0)
8103         (and:DI (match_dup 0)
8104                 (match_dup 1)))]
8105   "")
8107 ;; Split a load of a large constant into the appropriate five-instruction
8108 ;; sequence.  Handle anything in a constant number of insns.
8109 ;; When non-easy constants can go in the TOC, this should use
8110 ;; easy_fp_constant predicate.
8111 (define_split
8112   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8113         (match_operand:DI 1 "const_int_operand" ""))]
8114   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8115   [(set (match_dup 0) (match_dup 2))
8116    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8117   "
8119   if (rs6000_emit_set_const (operands[0], operands[1]))
8120     DONE;
8121   else
8122     FAIL;
8125 (define_split
8126   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8127         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8128   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8129   [(set (match_dup 0) (match_dup 2))
8130    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8131   "
8133   if (rs6000_emit_set_const (operands[0], operands[1]))
8134     DONE;
8135   else
8136     FAIL;
8139 (define_split
8140   [(set (match_operand:DI 0 "altivec_register_operand" "")
8141         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8142   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8143   [(const_int 0)]
8145   rtx op0 = operands[0];
8146   rtx op1 = operands[1];
8147   int r = REGNO (op0);
8148   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8150   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8151   if (op1 != const0_rtx && op1 != constm1_rtx)
8152     {
8153       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8154       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8155     }
8156   DONE;
8159 (define_split
8160   [(set (match_operand:DI 0 "altivec_register_operand" "")
8161         (match_operand:DI 1 "xxspltib_constant_split" ""))]
8162   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8163   [(const_int 0)]
8165   rtx op0 = operands[0];
8166   rtx op1 = operands[1];
8167   int r = REGNO (op0);
8168   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8170   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8171   emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8172   DONE;
8176 ;; TImode/PTImode is similar, except that we usually want to compute the
8177 ;; address into a register and use lsi/stsi (the exception is during reload).
8179 (define_insn "*mov<mode>_string"
8180   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8181         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8182   "! TARGET_POWERPC64
8183    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8184    && (gpc_reg_operand (operands[0], <MODE>mode)
8185        || gpc_reg_operand (operands[1], <MODE>mode))"
8186   "*
8188   switch (which_alternative)
8189     {
8190     default:
8191       gcc_unreachable ();
8192     case 0:
8193       if (TARGET_STRING)
8194         return \"stswi %1,%P0,16\";
8195       /* FALLTHRU */
8196     case 1:
8197       return \"#\";
8198     case 2:
8199       /* If the address is not used in the output, we can use lsi.  Otherwise,
8200          fall through to generating four loads.  */
8201       if (TARGET_STRING
8202           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8203         return \"lswi %0,%P1,16\";
8204       /* fall through */
8205     case 3:
8206     case 4:
8207     case 5:
8208       return \"#\";
8209     }
8211   [(set_attr "type" "store,store,load,load,*,*")
8212    (set_attr "update" "yes")
8213    (set_attr "indexed" "yes")
8214    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8215                                           (const_string "always")
8216                                           (const_string "conditional")))])
8218 (define_insn "*mov<mode>_ppc64"
8219   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8220         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8221   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8222    && (gpc_reg_operand (operands[0], <MODE>mode)
8223        || gpc_reg_operand (operands[1], <MODE>mode)))"
8225   return rs6000_output_move_128bit (operands);
8227   [(set_attr "type" "store,store,load,load,*,*")
8228    (set_attr "length" "8")])
8230 (define_split
8231   [(set (match_operand:TI2 0 "int_reg_operand" "")
8232         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8233   "TARGET_POWERPC64
8234    && (VECTOR_MEM_NONE_P (<MODE>mode)
8235        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8236   [(set (match_dup 2) (match_dup 4))
8237    (set (match_dup 3) (match_dup 5))]
8238   "
8240   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8241                                        <MODE>mode);
8242   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8243                                        <MODE>mode);
8244   if (CONST_WIDE_INT_P (operands[1]))
8245     {
8246       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8247       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8248     }
8249   else if (CONST_INT_P (operands[1]))
8250     {
8251       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8252       operands[5] = operands[1];
8253     }
8254   else
8255     FAIL;
8258 (define_split
8259   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8260         (match_operand:TI2 1 "input_operand" ""))]
8261   "reload_completed
8262    && gpr_or_gpr_p (operands[0], operands[1])
8263    && !direct_move_p (operands[0], operands[1])
8264    && !quad_load_store_p (operands[0], operands[1])"
8265   [(pc)]
8266 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8268 (define_expand "load_multiple"
8269   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8270                           (match_operand:SI 1 "" ""))
8271                      (use (match_operand:SI 2 "" ""))])]
8272   "TARGET_STRING && !TARGET_POWERPC64"
8273   "
8275   int regno;
8276   int count;
8277   rtx op1;
8278   int i;
8280   /* Support only loading a constant number of fixed-point registers from
8281      memory and only bother with this if more than two; the machine
8282      doesn't support more than eight.  */
8283   if (GET_CODE (operands[2]) != CONST_INT
8284       || INTVAL (operands[2]) <= 2
8285       || INTVAL (operands[2]) > 8
8286       || GET_CODE (operands[1]) != MEM
8287       || GET_CODE (operands[0]) != REG
8288       || REGNO (operands[0]) >= 32)
8289     FAIL;
8291   count = INTVAL (operands[2]);
8292   regno = REGNO (operands[0]);
8294   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8295   op1 = replace_equiv_address (operands[1],
8296                                force_reg (SImode, XEXP (operands[1], 0)));
8298   for (i = 0; i < count; i++)
8299     XVECEXP (operands[3], 0, i)
8300       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8301                      adjust_address_nv (op1, SImode, i * 4));
8304 (define_insn "*ldmsi8"
8305   [(match_parallel 0 "load_multiple_operation"
8306     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8307           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8308      (set (match_operand:SI 3 "gpc_reg_operand" "")
8309           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8310      (set (match_operand:SI 4 "gpc_reg_operand" "")
8311           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8312      (set (match_operand:SI 5 "gpc_reg_operand" "")
8313           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8314      (set (match_operand:SI 6 "gpc_reg_operand" "")
8315           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8316      (set (match_operand:SI 7 "gpc_reg_operand" "")
8317           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8318      (set (match_operand:SI 8 "gpc_reg_operand" "")
8319           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8320      (set (match_operand:SI 9 "gpc_reg_operand" "")
8321           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8322   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8323   "*
8324 { return rs6000_output_load_multiple (operands); }"
8325   [(set_attr "type" "load")
8326    (set_attr "update" "yes")
8327    (set_attr "indexed" "yes")
8328    (set_attr "length" "32")])
8330 (define_insn "*ldmsi7"
8331   [(match_parallel 0 "load_multiple_operation"
8332     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8333           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8334      (set (match_operand:SI 3 "gpc_reg_operand" "")
8335           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8336      (set (match_operand:SI 4 "gpc_reg_operand" "")
8337           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8338      (set (match_operand:SI 5 "gpc_reg_operand" "")
8339           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8340      (set (match_operand:SI 6 "gpc_reg_operand" "")
8341           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8342      (set (match_operand:SI 7 "gpc_reg_operand" "")
8343           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8344      (set (match_operand:SI 8 "gpc_reg_operand" "")
8345           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8346   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8347   "*
8348 { return rs6000_output_load_multiple (operands); }"
8349   [(set_attr "type" "load")
8350    (set_attr "update" "yes")
8351    (set_attr "indexed" "yes")
8352    (set_attr "length" "32")])
8354 (define_insn "*ldmsi6"
8355   [(match_parallel 0 "load_multiple_operation"
8356     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8357           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8358      (set (match_operand:SI 3 "gpc_reg_operand" "")
8359           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8360      (set (match_operand:SI 4 "gpc_reg_operand" "")
8361           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8362      (set (match_operand:SI 5 "gpc_reg_operand" "")
8363           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8364      (set (match_operand:SI 6 "gpc_reg_operand" "")
8365           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8366      (set (match_operand:SI 7 "gpc_reg_operand" "")
8367           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8368   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8369   "*
8370 { return rs6000_output_load_multiple (operands); }"
8371   [(set_attr "type" "load")
8372    (set_attr "update" "yes")
8373    (set_attr "indexed" "yes")
8374    (set_attr "length" "32")])
8376 (define_insn "*ldmsi5"
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   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8389   "*
8390 { return rs6000_output_load_multiple (operands); }"
8391   [(set_attr "type" "load")
8392    (set_attr "update" "yes")
8393    (set_attr "indexed" "yes")
8394    (set_attr "length" "32")])
8396 (define_insn "*ldmsi4"
8397   [(match_parallel 0 "load_multiple_operation"
8398     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8399           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8400      (set (match_operand:SI 3 "gpc_reg_operand" "")
8401           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8402      (set (match_operand:SI 4 "gpc_reg_operand" "")
8403           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8404      (set (match_operand:SI 5 "gpc_reg_operand" "")
8405           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8406   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8407   "*
8408 { return rs6000_output_load_multiple (operands); }"
8409   [(set_attr "type" "load")
8410    (set_attr "update" "yes")
8411    (set_attr "indexed" "yes")
8412    (set_attr "length" "32")])
8414 (define_insn "*ldmsi3"
8415   [(match_parallel 0 "load_multiple_operation"
8416     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8417           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8418      (set (match_operand:SI 3 "gpc_reg_operand" "")
8419           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8420      (set (match_operand:SI 4 "gpc_reg_operand" "")
8421           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8422   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8423   "*
8424 { return rs6000_output_load_multiple (operands); }"
8425   [(set_attr "type" "load")
8426    (set_attr "update" "yes")
8427    (set_attr "indexed" "yes")
8428    (set_attr "length" "32")])
8430 (define_expand "store_multiple"
8431   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8432                           (match_operand:SI 1 "" ""))
8433                      (clobber (scratch:SI))
8434                      (use (match_operand:SI 2 "" ""))])]
8435   "TARGET_STRING && !TARGET_POWERPC64"
8436   "
8438   int regno;
8439   int count;
8440   rtx to;
8441   rtx op0;
8442   int i;
8444   /* Support only storing a constant number of fixed-point registers to
8445      memory and only bother with this if more than two; the machine
8446      doesn't support more than eight.  */
8447   if (GET_CODE (operands[2]) != CONST_INT
8448       || INTVAL (operands[2]) <= 2
8449       || INTVAL (operands[2]) > 8
8450       || GET_CODE (operands[0]) != MEM
8451       || GET_CODE (operands[1]) != REG
8452       || REGNO (operands[1]) >= 32)
8453     FAIL;
8455   count = INTVAL (operands[2]);
8456   regno = REGNO (operands[1]);
8458   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8459   to = force_reg (SImode, XEXP (operands[0], 0));
8460   op0 = replace_equiv_address (operands[0], to);
8462   XVECEXP (operands[3], 0, 0)
8463     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8464   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8465                                                  gen_rtx_SCRATCH (SImode));
8467   for (i = 1; i < count; i++)
8468     XVECEXP (operands[3], 0, i + 1)
8469       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8470                      gen_rtx_REG (SImode, regno + i));
8473 (define_insn "*stmsi8"
8474   [(match_parallel 0 "store_multiple_operation"
8475     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8476           (match_operand:SI 2 "gpc_reg_operand" "r"))
8477      (clobber (match_scratch:SI 3 "=X"))
8478      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8479           (match_operand:SI 4 "gpc_reg_operand" "r"))
8480      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8481           (match_operand:SI 5 "gpc_reg_operand" "r"))
8482      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8483           (match_operand:SI 6 "gpc_reg_operand" "r"))
8484      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8485           (match_operand:SI 7 "gpc_reg_operand" "r"))
8486      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8487           (match_operand:SI 8 "gpc_reg_operand" "r"))
8488      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8489           (match_operand:SI 9 "gpc_reg_operand" "r"))
8490      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8491           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8492   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8493   "stswi %2,%1,%O0"
8494   [(set_attr "type" "store")
8495    (set_attr "update" "yes")
8496    (set_attr "indexed" "yes")
8497    (set_attr "cell_micro" "always")])
8499 (define_insn "*stmsi7"
8500   [(match_parallel 0 "store_multiple_operation"
8501     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8502           (match_operand:SI 2 "gpc_reg_operand" "r"))
8503      (clobber (match_scratch:SI 3 "=X"))
8504      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8505           (match_operand:SI 4 "gpc_reg_operand" "r"))
8506      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8507           (match_operand:SI 5 "gpc_reg_operand" "r"))
8508      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8509           (match_operand:SI 6 "gpc_reg_operand" "r"))
8510      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8511           (match_operand:SI 7 "gpc_reg_operand" "r"))
8512      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8513           (match_operand:SI 8 "gpc_reg_operand" "r"))
8514      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8515           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8516   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8517   "stswi %2,%1,%O0"
8518   [(set_attr "type" "store")
8519    (set_attr "update" "yes")
8520    (set_attr "indexed" "yes")
8521    (set_attr "cell_micro" "always")])
8523 (define_insn "*stmsi6"
8524   [(match_parallel 0 "store_multiple_operation"
8525     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8526           (match_operand:SI 2 "gpc_reg_operand" "r"))
8527      (clobber (match_scratch:SI 3 "=X"))
8528      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8529           (match_operand:SI 4 "gpc_reg_operand" "r"))
8530      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8531           (match_operand:SI 5 "gpc_reg_operand" "r"))
8532      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8533           (match_operand:SI 6 "gpc_reg_operand" "r"))
8534      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8535           (match_operand:SI 7 "gpc_reg_operand" "r"))
8536      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8537           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8538   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8539   "stswi %2,%1,%O0"
8540   [(set_attr "type" "store")
8541    (set_attr "update" "yes")
8542    (set_attr "indexed" "yes")
8543    (set_attr "cell_micro" "always")])
8545 (define_insn "*stmsi5"
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   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8559   "stswi %2,%1,%O0"
8560   [(set_attr "type" "store")
8561    (set_attr "update" "yes")
8562    (set_attr "indexed" "yes")
8563    (set_attr "cell_micro" "always")])
8565 (define_insn "*stmsi4"
8566   [(match_parallel 0 "store_multiple_operation"
8567     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8568           (match_operand:SI 2 "gpc_reg_operand" "r"))
8569      (clobber (match_scratch:SI 3 "=X"))
8570      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8571           (match_operand:SI 4 "gpc_reg_operand" "r"))
8572      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8573           (match_operand:SI 5 "gpc_reg_operand" "r"))
8574      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8575           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8576   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8577   "stswi %2,%1,%O0"
8578   [(set_attr "type" "store")
8579    (set_attr "update" "yes")
8580    (set_attr "indexed" "yes")
8581    (set_attr "cell_micro" "always")])
8583 (define_insn "*stmsi3"
8584   [(match_parallel 0 "store_multiple_operation"
8585     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8586           (match_operand:SI 2 "gpc_reg_operand" "r"))
8587      (clobber (match_scratch:SI 3 "=X"))
8588      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8589           (match_operand:SI 4 "gpc_reg_operand" "r"))
8590      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8591           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8592   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8593   "stswi %2,%1,%O0"
8594   [(set_attr "type" "store")
8595    (set_attr "update" "yes")
8596    (set_attr "indexed" "yes")
8597    (set_attr "cell_micro" "always")])
8599 (define_expand "setmemsi"
8600   [(parallel [(set (match_operand:BLK 0 "" "")
8601                    (match_operand 2 "const_int_operand" ""))
8602               (use (match_operand:SI 1 "" ""))
8603               (use (match_operand:SI 3 "" ""))])]
8604   ""
8605   "
8607   /* If value to set is not zero, use the library routine.  */
8608   if (operands[2] != const0_rtx)
8609     FAIL;
8611   if (expand_block_clear (operands))
8612     DONE;
8613   else
8614     FAIL;
8617 ;; String/block compare insn.
8618 ;; Argument 0 is the target (result)
8619 ;; Argument 1 is the destination
8620 ;; Argument 2 is the source
8621 ;; Argument 3 is the length
8622 ;; Argument 4 is the alignment
8624 (define_expand "cmpmemsi"
8625   [(parallel [(set (match_operand:SI 0)
8626                (compare:SI (match_operand:BLK 1)
8627                            (match_operand:BLK 2)))
8628               (use (match_operand:SI 3))
8629               (use (match_operand:SI 4))])]
8630   ""
8632   if (expand_block_compare (operands))
8633     DONE;
8634   else  
8635     FAIL;
8638 ;; String/block move insn.
8639 ;; Argument 0 is the destination
8640 ;; Argument 1 is the source
8641 ;; Argument 2 is the length
8642 ;; Argument 3 is the alignment
8644 (define_expand "movmemsi"
8645   [(parallel [(set (match_operand:BLK 0 "" "")
8646                    (match_operand:BLK 1 "" ""))
8647               (use (match_operand:SI 2 "" ""))
8648               (use (match_operand:SI 3 "" ""))])]
8649   ""
8650   "
8652   if (expand_block_move (operands))
8653     DONE;
8654   else
8655     FAIL;
8658 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8659 ;; register allocator doesn't have a clue about allocating 8 word registers.
8660 ;; rD/rS = r5 is preferred, efficient form.
8661 (define_expand "movmemsi_8reg"
8662   [(parallel [(set (match_operand 0 "" "")
8663                    (match_operand 1 "" ""))
8664               (use (match_operand 2 "" ""))
8665               (use (match_operand 3 "" ""))
8666               (clobber (reg:SI  5))
8667               (clobber (reg:SI  6))
8668               (clobber (reg:SI  7))
8669               (clobber (reg:SI  8))
8670               (clobber (reg:SI  9))
8671               (clobber (reg:SI 10))
8672               (clobber (reg:SI 11))
8673               (clobber (reg:SI 12))
8674               (clobber (match_scratch:SI 4 ""))])]
8675   "TARGET_STRING"
8676   "")
8678 (define_insn ""
8679   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8680         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8681    (use (match_operand:SI 2 "immediate_operand" "i"))
8682    (use (match_operand:SI 3 "immediate_operand" "i"))
8683    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8684    (clobber (reg:SI  6))
8685    (clobber (reg:SI  7))
8686    (clobber (reg:SI  8))
8687    (clobber (reg:SI  9))
8688    (clobber (reg:SI 10))
8689    (clobber (reg:SI 11))
8690    (clobber (reg:SI 12))
8691    (clobber (match_scratch:SI 5 "=X"))]
8692   "TARGET_STRING
8693    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8694        || INTVAL (operands[2]) == 0)
8695    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8696    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8697    && REGNO (operands[4]) == 5"
8698   "lswi %4,%1,%2\;stswi %4,%0,%2"
8699   [(set_attr "type" "store")
8700    (set_attr "update" "yes")
8701    (set_attr "indexed" "yes")
8702    (set_attr "cell_micro" "always")
8703    (set_attr "length" "8")])
8705 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8706 ;; register allocator doesn't have a clue about allocating 6 word registers.
8707 ;; rD/rS = r5 is preferred, efficient form.
8708 (define_expand "movmemsi_6reg"
8709   [(parallel [(set (match_operand 0 "" "")
8710                    (match_operand 1 "" ""))
8711               (use (match_operand 2 "" ""))
8712               (use (match_operand 3 "" ""))
8713               (clobber (reg:SI  5))
8714               (clobber (reg:SI  6))
8715               (clobber (reg:SI  7))
8716               (clobber (reg:SI  8))
8717               (clobber (reg:SI  9))
8718               (clobber (reg:SI 10))
8719               (clobber (match_scratch:SI 4 ""))])]
8720   "TARGET_STRING"
8721   "")
8723 (define_insn ""
8724   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8725         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8726    (use (match_operand:SI 2 "immediate_operand" "i"))
8727    (use (match_operand:SI 3 "immediate_operand" "i"))
8728    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8729    (clobber (reg:SI  6))
8730    (clobber (reg:SI  7))
8731    (clobber (reg:SI  8))
8732    (clobber (reg:SI  9))
8733    (clobber (reg:SI 10))
8734    (clobber (match_scratch:SI 5 "=X"))]
8735   "TARGET_STRING
8736    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8737    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8738    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8739    && REGNO (operands[4]) == 5"
8740   "lswi %4,%1,%2\;stswi %4,%0,%2"
8741   [(set_attr "type" "store")
8742    (set_attr "update" "yes")
8743    (set_attr "indexed" "yes")
8744    (set_attr "cell_micro" "always")
8745    (set_attr "length" "8")])
8747 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8748 ;; problems with TImode.
8749 ;; rD/rS = r5 is preferred, efficient form.
8750 (define_expand "movmemsi_4reg"
8751   [(parallel [(set (match_operand 0 "" "")
8752                    (match_operand 1 "" ""))
8753               (use (match_operand 2 "" ""))
8754               (use (match_operand 3 "" ""))
8755               (clobber (reg:SI 5))
8756               (clobber (reg:SI 6))
8757               (clobber (reg:SI 7))
8758               (clobber (reg:SI 8))
8759               (clobber (match_scratch:SI 4 ""))])]
8760   "TARGET_STRING"
8761   "")
8763 (define_insn ""
8764   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8765         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8766    (use (match_operand:SI 2 "immediate_operand" "i"))
8767    (use (match_operand:SI 3 "immediate_operand" "i"))
8768    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8769    (clobber (reg:SI 6))
8770    (clobber (reg:SI 7))
8771    (clobber (reg:SI 8))
8772    (clobber (match_scratch:SI 5 "=X"))]
8773   "TARGET_STRING
8774    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8775    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8776    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8777    && REGNO (operands[4]) == 5"
8778   "lswi %4,%1,%2\;stswi %4,%0,%2"
8779   [(set_attr "type" "store")
8780    (set_attr "update" "yes")
8781    (set_attr "indexed" "yes")
8782    (set_attr "cell_micro" "always")
8783    (set_attr "length" "8")])
8785 ;; Move up to 8 bytes at a time.
8786 (define_expand "movmemsi_2reg"
8787   [(parallel [(set (match_operand 0 "" "")
8788                    (match_operand 1 "" ""))
8789               (use (match_operand 2 "" ""))
8790               (use (match_operand 3 "" ""))
8791               (clobber (match_scratch:DI 4 ""))
8792               (clobber (match_scratch:SI 5 ""))])]
8793   "TARGET_STRING && ! TARGET_POWERPC64"
8794   "")
8796 (define_insn ""
8797   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8798         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8799    (use (match_operand:SI 2 "immediate_operand" "i"))
8800    (use (match_operand:SI 3 "immediate_operand" "i"))
8801    (clobber (match_scratch:DI 4 "=&r"))
8802    (clobber (match_scratch:SI 5 "=X"))]
8803   "TARGET_STRING && ! TARGET_POWERPC64
8804    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8805   "lswi %4,%1,%2\;stswi %4,%0,%2"
8806   [(set_attr "type" "store")
8807    (set_attr "update" "yes")
8808    (set_attr "indexed" "yes")
8809    (set_attr "cell_micro" "always")
8810    (set_attr "length" "8")])
8812 ;; Move up to 4 bytes at a time.
8813 (define_expand "movmemsi_1reg"
8814   [(parallel [(set (match_operand 0 "" "")
8815                    (match_operand 1 "" ""))
8816               (use (match_operand 2 "" ""))
8817               (use (match_operand 3 "" ""))
8818               (clobber (match_scratch:SI 4 ""))
8819               (clobber (match_scratch:SI 5 ""))])]
8820   "TARGET_STRING"
8821   "")
8823 (define_insn ""
8824   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8825         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8826    (use (match_operand:SI 2 "immediate_operand" "i"))
8827    (use (match_operand:SI 3 "immediate_operand" "i"))
8828    (clobber (match_scratch:SI 4 "=&r"))
8829    (clobber (match_scratch:SI 5 "=X"))]
8830   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8831   "lswi %4,%1,%2\;stswi %4,%0,%2"
8832   [(set_attr "type" "store")
8833    (set_attr "update" "yes")
8834    (set_attr "indexed" "yes")
8835    (set_attr "cell_micro" "always")
8836    (set_attr "length" "8")])
8838 ;; Define insns that do load or store with update.  Some of these we can
8839 ;; get by using pre-decrement or pre-increment, but the hardware can also
8840 ;; do cases where the increment is not the size of the object.
8842 ;; In all these cases, we use operands 0 and 1 for the register being
8843 ;; incremented because those are the operands that local-alloc will
8844 ;; tie and these are the pair most likely to be tieable (and the ones
8845 ;; that will benefit the most).
8847 (define_insn "*movdi_update1"
8848   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8849         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8850                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8851    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8852         (plus:DI (match_dup 1) (match_dup 2)))]
8853   "TARGET_POWERPC64 && TARGET_UPDATE
8854    && (!avoiding_indexed_address_p (DImode)
8855        || !gpc_reg_operand (operands[2], DImode))"
8856   "@
8857    ldux %3,%0,%2
8858    ldu %3,%2(%0)"
8859   [(set_attr "type" "load")
8860    (set_attr "update" "yes")
8861    (set_attr "indexed" "yes,no")])
8863 (define_insn "movdi_<mode>_update"
8864   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8865                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8866         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8867    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8868         (plus:P (match_dup 1) (match_dup 2)))]
8869   "TARGET_POWERPC64 && TARGET_UPDATE
8870    && (!avoiding_indexed_address_p (Pmode)
8871        || !gpc_reg_operand (operands[2], Pmode)
8872        || (REG_P (operands[0])
8873            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8874   "@
8875    stdux %3,%0,%2
8876    stdu %3,%2(%0)"
8877   [(set_attr "type" "store")
8878    (set_attr "update" "yes")
8879    (set_attr "indexed" "yes,no")])
8881 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8882 ;; needed for stack allocation, even if the user passes -mno-update.
8883 (define_insn "movdi_<mode>_update_stack"
8884   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8885                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8886         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8887    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8888         (plus:P (match_dup 1) (match_dup 2)))]
8889   "TARGET_POWERPC64"
8890   "@
8891    stdux %3,%0,%2
8892    stdu %3,%2(%0)"
8893   [(set_attr "type" "store")
8894    (set_attr "update" "yes")
8895    (set_attr "indexed" "yes,no")])
8897 (define_insn "*movsi_update1"
8898   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8899         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8900                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8901    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8902         (plus:SI (match_dup 1) (match_dup 2)))]
8903   "TARGET_UPDATE
8904    && (!avoiding_indexed_address_p (SImode)
8905        || !gpc_reg_operand (operands[2], SImode))"
8906   "@
8907    lwzux %3,%0,%2
8908    lwzu %3,%2(%0)"
8909   [(set_attr "type" "load")
8910    (set_attr "update" "yes")
8911    (set_attr "indexed" "yes,no")])
8913 (define_insn "*movsi_update2"
8914   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8915         (sign_extend:DI
8916          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8917                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8918    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8919         (plus:DI (match_dup 1) (match_dup 2)))]
8920   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8921    && !avoiding_indexed_address_p (DImode)"
8922   "lwaux %3,%0,%2"
8923   [(set_attr "type" "load")
8924    (set_attr "sign_extend" "yes")
8925    (set_attr "update" "yes")
8926    (set_attr "indexed" "yes")])
8928 (define_insn "movsi_update"
8929   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8930                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8931         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8932    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8933         (plus:SI (match_dup 1) (match_dup 2)))]
8934   "TARGET_UPDATE
8935    && (!avoiding_indexed_address_p (SImode)
8936        || !gpc_reg_operand (operands[2], SImode)
8937        || (REG_P (operands[0])
8938            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8939   "@
8940    stwux %3,%0,%2
8941    stwu %3,%2(%0)"
8942   [(set_attr "type" "store")
8943    (set_attr "update" "yes")
8944    (set_attr "indexed" "yes,no")])
8946 ;; This is an unconditional pattern; needed for stack allocation, even
8947 ;; if the user passes -mno-update.
8948 (define_insn "movsi_update_stack"
8949   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8950                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8951         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8952    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8953         (plus:SI (match_dup 1) (match_dup 2)))]
8954   ""
8955   "@
8956    stwux %3,%0,%2
8957    stwu %3,%2(%0)"
8958   [(set_attr "type" "store")
8959    (set_attr "update" "yes")
8960    (set_attr "indexed" "yes,no")])
8962 (define_insn "*movhi_update1"
8963   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8964         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8965                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8966    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8967         (plus:SI (match_dup 1) (match_dup 2)))]
8968   "TARGET_UPDATE
8969    && (!avoiding_indexed_address_p (SImode)
8970        || !gpc_reg_operand (operands[2], SImode))"
8971   "@
8972    lhzux %3,%0,%2
8973    lhzu %3,%2(%0)"
8974   [(set_attr "type" "load")
8975    (set_attr "update" "yes")
8976    (set_attr "indexed" "yes,no")])
8978 (define_insn "*movhi_update2"
8979   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8980         (zero_extend:SI
8981          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8982                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8983    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8984         (plus:SI (match_dup 1) (match_dup 2)))]
8985   "TARGET_UPDATE
8986    && (!avoiding_indexed_address_p (SImode)
8987        || !gpc_reg_operand (operands[2], SImode))"
8988   "@
8989    lhzux %3,%0,%2
8990    lhzu %3,%2(%0)"
8991   [(set_attr "type" "load")
8992    (set_attr "update" "yes")
8993    (set_attr "indexed" "yes,no")])
8995 (define_insn "*movhi_update3"
8996   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8997         (sign_extend:SI
8998          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8999                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9000    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9001         (plus:SI (match_dup 1) (match_dup 2)))]
9002   "TARGET_UPDATE && rs6000_gen_cell_microcode
9003    && (!avoiding_indexed_address_p (SImode)
9004        || !gpc_reg_operand (operands[2], SImode))"
9005   "@
9006    lhaux %3,%0,%2
9007    lhau %3,%2(%0)"
9008   [(set_attr "type" "load")
9009    (set_attr "sign_extend" "yes")
9010    (set_attr "update" "yes")
9011    (set_attr "indexed" "yes,no")])
9013 (define_insn "*movhi_update4"
9014   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9015                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9016         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9017    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9018         (plus:SI (match_dup 1) (match_dup 2)))]
9019   "TARGET_UPDATE
9020    && (!avoiding_indexed_address_p (SImode)
9021        || !gpc_reg_operand (operands[2], SImode))"
9022   "@
9023    sthux %3,%0,%2
9024    sthu %3,%2(%0)"
9025   [(set_attr "type" "store")
9026    (set_attr "update" "yes")
9027    (set_attr "indexed" "yes,no")])
9029 (define_insn "*movqi_update1"
9030   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9031         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9032                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9033    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9034         (plus:SI (match_dup 1) (match_dup 2)))]
9035   "TARGET_UPDATE
9036    && (!avoiding_indexed_address_p (SImode)
9037        || !gpc_reg_operand (operands[2], SImode))"
9038   "@
9039    lbzux %3,%0,%2
9040    lbzu %3,%2(%0)"
9041   [(set_attr "type" "load")
9042    (set_attr "update" "yes")
9043    (set_attr "indexed" "yes,no")])
9045 (define_insn "*movqi_update2"
9046   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9047         (zero_extend:SI
9048          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9049                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9050    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9051         (plus:SI (match_dup 1) (match_dup 2)))]
9052   "TARGET_UPDATE
9053    && (!avoiding_indexed_address_p (SImode)
9054        || !gpc_reg_operand (operands[2], SImode))"
9055   "@
9056    lbzux %3,%0,%2
9057    lbzu %3,%2(%0)"
9058   [(set_attr "type" "load")
9059    (set_attr "update" "yes")
9060    (set_attr "indexed" "yes,no")])
9062 (define_insn "*movqi_update3"
9063   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9064                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9065         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9066    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9067         (plus:SI (match_dup 1) (match_dup 2)))]
9068   "TARGET_UPDATE
9069    && (!avoiding_indexed_address_p (SImode)
9070        || !gpc_reg_operand (operands[2], SImode))"
9071   "@
9072    stbux %3,%0,%2
9073    stbu %3,%2(%0)"
9074   [(set_attr "type" "store")
9075    (set_attr "update" "yes")
9076    (set_attr "indexed" "yes,no")])
9078 (define_insn "*movsf_update1"
9079   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9080         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9081                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9082    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9083         (plus:SI (match_dup 1) (match_dup 2)))]
9084   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9085    && (!avoiding_indexed_address_p (SImode)
9086        || !gpc_reg_operand (operands[2], SImode))"
9087   "@
9088    lfsux %3,%0,%2
9089    lfsu %3,%2(%0)"
9090   [(set_attr "type" "fpload")
9091    (set_attr "update" "yes")
9092    (set_attr "indexed" "yes,no")])
9094 (define_insn "*movsf_update2"
9095   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9096                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9097         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9098    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9099         (plus:SI (match_dup 1) (match_dup 2)))]
9100   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9101    && (!avoiding_indexed_address_p (SImode)
9102        || !gpc_reg_operand (operands[2], SImode))"
9103   "@
9104    stfsux %3,%0,%2
9105    stfsu %3,%2(%0)"
9106   [(set_attr "type" "fpstore")
9107    (set_attr "update" "yes")
9108    (set_attr "indexed" "yes,no")])
9110 (define_insn "*movsf_update3"
9111   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9112         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9113                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9114    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9115         (plus:SI (match_dup 1) (match_dup 2)))]
9116   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9117    && (!avoiding_indexed_address_p (SImode)
9118        || !gpc_reg_operand (operands[2], SImode))"
9119   "@
9120    lwzux %3,%0,%2
9121    lwzu %3,%2(%0)"
9122   [(set_attr "type" "load")
9123    (set_attr "update" "yes")
9124    (set_attr "indexed" "yes,no")])
9126 (define_insn "*movsf_update4"
9127   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9128                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9129         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9130    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9131         (plus:SI (match_dup 1) (match_dup 2)))]
9132   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9133    && (!avoiding_indexed_address_p (SImode)
9134        || !gpc_reg_operand (operands[2], SImode))"
9135   "@
9136    stwux %3,%0,%2
9137    stwu %3,%2(%0)"
9138   [(set_attr "type" "store")
9139    (set_attr "update" "yes")
9140    (set_attr "indexed" "yes,no")])
9142 (define_insn "*movdf_update1"
9143   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9144         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9145                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9146    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9147         (plus:SI (match_dup 1) (match_dup 2)))]
9148   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9149    && (!avoiding_indexed_address_p (SImode)
9150        || !gpc_reg_operand (operands[2], SImode))"
9151   "@
9152    lfdux %3,%0,%2
9153    lfdu %3,%2(%0)"
9154   [(set_attr "type" "fpload")
9155    (set_attr "update" "yes")
9156    (set_attr "indexed" "yes,no")
9157    (set_attr "size" "64")])
9159 (define_insn "*movdf_update2"
9160   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9161                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9162         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9163    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9164         (plus:SI (match_dup 1) (match_dup 2)))]
9165   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9166    && (!avoiding_indexed_address_p (SImode)
9167        || !gpc_reg_operand (operands[2], SImode))"
9168   "@
9169    stfdux %3,%0,%2
9170    stfdu %3,%2(%0)"
9171   [(set_attr "type" "fpstore")
9172    (set_attr "update" "yes")
9173    (set_attr "indexed" "yes,no")])
9176 ;; After inserting conditional returns we can sometimes have
9177 ;; unnecessary register moves.  Unfortunately we cannot have a
9178 ;; modeless peephole here, because some single SImode sets have early
9179 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9180 ;; sequences, using get_attr_length here will smash the operands
9181 ;; array.  Neither is there an early_cobbler_p predicate.
9182 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9183 ;; Also this optimization interferes with scalars going into
9184 ;; altivec registers (the code does reloading through the FPRs).
9185 (define_peephole2
9186   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9187         (match_operand:DF 1 "any_operand" ""))
9188    (set (match_operand:DF 2 "gpc_reg_operand" "")
9189         (match_dup 0))]
9190   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9191    && !TARGET_UPPER_REGS_DF
9192    && peep2_reg_dead_p (2, operands[0])"
9193   [(set (match_dup 2) (match_dup 1))])
9195 (define_peephole2
9196   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9197         (match_operand:SF 1 "any_operand" ""))
9198    (set (match_operand:SF 2 "gpc_reg_operand" "")
9199         (match_dup 0))]
9200   "!TARGET_UPPER_REGS_SF
9201    && peep2_reg_dead_p (2, operands[0])"
9202   [(set (match_dup 2) (match_dup 1))])
9205 ;; TLS support.
9207 ;; Mode attributes for different ABIs.
9208 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9209 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9210 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9211 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9213 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9214   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9215         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9216               (match_operand 4 "" "g")))
9217    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9218                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9219                    UNSPEC_TLSGD)
9220    (clobber (reg:SI LR_REGNO))]
9221   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9223   if (TARGET_CMODEL != CMODEL_SMALL)
9224     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9225            "bl %z3\;nop";
9226   else
9227     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9229   "&& TARGET_TLS_MARKERS"
9230   [(set (match_dup 0)
9231         (unspec:TLSmode [(match_dup 1)
9232                          (match_dup 2)]
9233                         UNSPEC_TLSGD))
9234    (parallel [(set (match_dup 0)
9235                    (call (mem:TLSmode (match_dup 3))
9236                          (match_dup 4)))
9237               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9238               (clobber (reg:SI LR_REGNO))])]
9239   ""
9240   [(set_attr "type" "two")
9241    (set (attr "length")
9242      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9243                    (const_int 16)
9244                    (const_int 12)))])
9246 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9247   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9248         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9249               (match_operand 4 "" "g")))
9250    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9251                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9252                    UNSPEC_TLSGD)
9253    (clobber (reg:SI LR_REGNO))]
9254   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9256   if (flag_pic)
9257     {
9258       if (TARGET_SECURE_PLT && flag_pic == 2)
9259         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9260       else
9261         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9262     }
9263   else
9264     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9266   "&& TARGET_TLS_MARKERS"
9267   [(set (match_dup 0)
9268         (unspec:TLSmode [(match_dup 1)
9269                          (match_dup 2)]
9270                         UNSPEC_TLSGD))
9271    (parallel [(set (match_dup 0)
9272                    (call (mem:TLSmode (match_dup 3))
9273                          (match_dup 4)))
9274               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9275               (clobber (reg:SI LR_REGNO))])]
9276   ""
9277   [(set_attr "type" "two")
9278    (set_attr "length" "8")])
9280 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9281   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9282         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9283                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9284                         UNSPEC_TLSGD))]
9285   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9286   "addi %0,%1,%2@got@tlsgd"
9287   "&& TARGET_CMODEL != CMODEL_SMALL"
9288   [(set (match_dup 3)
9289         (high:TLSmode
9290             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9291    (set (match_dup 0)
9292         (lo_sum:TLSmode (match_dup 3)
9293             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9294   "
9296   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9298   [(set (attr "length")
9299      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9300                    (const_int 8)
9301                    (const_int 4)))])
9303 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9304   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9305      (high:TLSmode
9306        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9307                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9308                        UNSPEC_TLSGD)))]
9309   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9310   "addis %0,%1,%2@got@tlsgd@ha"
9311   [(set_attr "length" "4")])
9313 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9314   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9315      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9316        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9317                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9318                        UNSPEC_TLSGD)))]
9319   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9320   "addi %0,%1,%2@got@tlsgd@l"
9321   [(set_attr "length" "4")])
9323 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9324   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9325         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9326               (match_operand 2 "" "g")))
9327    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9328                    UNSPEC_TLSGD)
9329    (clobber (reg:SI LR_REGNO))]
9330   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9331    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9332   "bl %z1(%3@tlsgd)\;nop"
9333   [(set_attr "type" "branch")
9334    (set_attr "length" "8")])
9336 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9337   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9338         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9339               (match_operand 2 "" "g")))
9340    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9341                    UNSPEC_TLSGD)
9342    (clobber (reg:SI LR_REGNO))]
9343   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9345   if (flag_pic)
9346     {
9347       if (TARGET_SECURE_PLT && flag_pic == 2)
9348         return "bl %z1+32768(%3@tlsgd)@plt";
9349       return "bl %z1(%3@tlsgd)@plt";
9350     }
9351   return "bl %z1(%3@tlsgd)";
9353   [(set_attr "type" "branch")
9354    (set_attr "length" "4")])
9356 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9357   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9358         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9359               (match_operand 3 "" "g")))
9360    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9361                    UNSPEC_TLSLD)
9362    (clobber (reg:SI LR_REGNO))]
9363   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9365   if (TARGET_CMODEL != CMODEL_SMALL)
9366     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9367            "bl %z2\;nop";
9368   else
9369     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9371   "&& TARGET_TLS_MARKERS"
9372   [(set (match_dup 0)
9373         (unspec:TLSmode [(match_dup 1)]
9374                         UNSPEC_TLSLD))
9375    (parallel [(set (match_dup 0)
9376                    (call (mem:TLSmode (match_dup 2))
9377                          (match_dup 3)))
9378               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9379               (clobber (reg:SI LR_REGNO))])]
9380   ""
9381   [(set_attr "type" "two")
9382    (set (attr "length")
9383      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9384                    (const_int 16)
9385                    (const_int 12)))])
9387 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9388   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9389         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9390               (match_operand 3 "" "g")))
9391    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9392                    UNSPEC_TLSLD)
9393    (clobber (reg:SI LR_REGNO))]
9394   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9396   if (flag_pic)
9397     {
9398       if (TARGET_SECURE_PLT && flag_pic == 2)
9399         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9400       else
9401         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9402     }
9403   else
9404     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9406   "&& TARGET_TLS_MARKERS"
9407   [(set (match_dup 0)
9408         (unspec:TLSmode [(match_dup 1)]
9409                         UNSPEC_TLSLD))
9410    (parallel [(set (match_dup 0)
9411                    (call (mem:TLSmode (match_dup 2))
9412                          (match_dup 3)))
9413               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9414               (clobber (reg:SI LR_REGNO))])]
9415   ""
9416   [(set_attr "length" "8")])
9418 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9419   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9420         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9421                         UNSPEC_TLSLD))]
9422   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9423   "addi %0,%1,%&@got@tlsld"
9424   "&& TARGET_CMODEL != CMODEL_SMALL"
9425   [(set (match_dup 2)
9426         (high:TLSmode
9427             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9428    (set (match_dup 0)
9429         (lo_sum:TLSmode (match_dup 2)
9430             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9431   "
9433   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9435   [(set (attr "length")
9436      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9437                    (const_int 8)
9438                    (const_int 4)))])
9440 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9441   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9442      (high:TLSmode
9443        (unspec:TLSmode [(const_int 0)
9444                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9445                        UNSPEC_TLSLD)))]
9446   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9447   "addis %0,%1,%&@got@tlsld@ha"
9448   [(set_attr "length" "4")])
9450 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9451   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9452      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9453        (unspec:TLSmode [(const_int 0)
9454                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9455                        UNSPEC_TLSLD)))]
9456   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9457   "addi %0,%1,%&@got@tlsld@l"
9458   [(set_attr "length" "4")])
9460 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9461   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9462         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9463               (match_operand 2 "" "g")))
9464    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9465    (clobber (reg:SI LR_REGNO))]
9466   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9467    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9468   "bl %z1(%&@tlsld)\;nop"
9469   [(set_attr "type" "branch")
9470    (set_attr "length" "8")])
9472 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9473   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9474         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9475               (match_operand 2 "" "g")))
9476    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9477    (clobber (reg:SI LR_REGNO))]
9478   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9480   if (flag_pic)
9481     {
9482       if (TARGET_SECURE_PLT && flag_pic == 2)
9483         return "bl %z1+32768(%&@tlsld)@plt";
9484       return "bl %z1(%&@tlsld)@plt";
9485     }
9486   return "bl %z1(%&@tlsld)";
9488   [(set_attr "type" "branch")
9489    (set_attr "length" "4")])
9491 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9492   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9493         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9494                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9495                         UNSPEC_TLSDTPREL))]
9496   "HAVE_AS_TLS"
9497   "addi %0,%1,%2@dtprel")
9499 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9500   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9501         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9502                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9503                         UNSPEC_TLSDTPRELHA))]
9504   "HAVE_AS_TLS"
9505   "addis %0,%1,%2@dtprel@ha")
9507 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9508   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9509         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9510                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9511                         UNSPEC_TLSDTPRELLO))]
9512   "HAVE_AS_TLS"
9513   "addi %0,%1,%2@dtprel@l")
9515 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9516   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9517         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9518                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9519                         UNSPEC_TLSGOTDTPREL))]
9520   "HAVE_AS_TLS"
9521   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9522   "&& TARGET_CMODEL != CMODEL_SMALL"
9523   [(set (match_dup 3)
9524         (high:TLSmode
9525             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9526    (set (match_dup 0)
9527         (lo_sum:TLSmode (match_dup 3)
9528             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9529   "
9531   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9533   [(set (attr "length")
9534      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9535                    (const_int 8)
9536                    (const_int 4)))])
9538 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9539   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9540      (high:TLSmode
9541        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9542                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9543                        UNSPEC_TLSGOTDTPREL)))]
9544   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9545   "addis %0,%1,%2@got@dtprel@ha"
9546   [(set_attr "length" "4")])
9548 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9549   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9550      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9551          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9552                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9553                          UNSPEC_TLSGOTDTPREL)))]
9554   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9555   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9556   [(set_attr "length" "4")])
9558 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9559   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9560         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9561                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9562                         UNSPEC_TLSTPREL))]
9563   "HAVE_AS_TLS"
9564   "addi %0,%1,%2@tprel")
9566 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9567   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9568         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9569                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9570                         UNSPEC_TLSTPRELHA))]
9571   "HAVE_AS_TLS"
9572   "addis %0,%1,%2@tprel@ha")
9574 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9575   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9576         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9577                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9578                         UNSPEC_TLSTPRELLO))]
9579   "HAVE_AS_TLS"
9580   "addi %0,%1,%2@tprel@l")
9582 ;; "b" output constraint here and on tls_tls input to support linker tls
9583 ;; optimization.  The linker may edit the instructions emitted by a
9584 ;; tls_got_tprel/tls_tls pair to addis,addi.
9585 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9586   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9587         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9588                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9589                         UNSPEC_TLSGOTTPREL))]
9590   "HAVE_AS_TLS"
9591   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9592   "&& TARGET_CMODEL != CMODEL_SMALL"
9593   [(set (match_dup 3)
9594         (high:TLSmode
9595             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9596    (set (match_dup 0)
9597         (lo_sum:TLSmode (match_dup 3)
9598             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9599   "
9601   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9603   [(set (attr "length")
9604      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9605                    (const_int 8)
9606                    (const_int 4)))])
9608 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9609   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9610      (high:TLSmode
9611        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9612                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9613                        UNSPEC_TLSGOTTPREL)))]
9614   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9615   "addis %0,%1,%2@got@tprel@ha"
9616   [(set_attr "length" "4")])
9618 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9619   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9620      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9621          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9622                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9623                          UNSPEC_TLSGOTTPREL)))]
9624   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9625   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9626   [(set_attr "length" "4")])
9628 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9629   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9630         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9631                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9632                         UNSPEC_TLSTLS))]
9633   "TARGET_ELF && HAVE_AS_TLS"
9634   "add %0,%1,%2@tls")
9636 (define_expand "tls_get_tpointer"
9637   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9638         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9639   "TARGET_XCOFF && HAVE_AS_TLS"
9640   "
9642   emit_insn (gen_tls_get_tpointer_internal ());
9643   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9644   DONE;
9647 (define_insn "tls_get_tpointer_internal"
9648   [(set (reg:SI 3)
9649         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9650    (clobber (reg:SI LR_REGNO))]
9651   "TARGET_XCOFF && HAVE_AS_TLS"
9652   "bla __get_tpointer")
9654 (define_expand "tls_get_addr<mode>"
9655   [(set (match_operand:P 0 "gpc_reg_operand" "")
9656         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9657                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9658   "TARGET_XCOFF && HAVE_AS_TLS"
9659   "
9661   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9662   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9663   emit_insn (gen_tls_get_addr_internal<mode> ());
9664   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9665   DONE;
9668 (define_insn "tls_get_addr_internal<mode>"
9669   [(set (reg:P 3)
9670         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9671    (clobber (reg:P 0))
9672    (clobber (reg:P 4))
9673    (clobber (reg:P 5))
9674    (clobber (reg:P 11))
9675    (clobber (reg:CC CR0_REGNO))
9676    (clobber (reg:P LR_REGNO))]
9677   "TARGET_XCOFF && HAVE_AS_TLS"
9678   "bla __tls_get_addr")
9680 ;; Next come insns related to the calling sequence.
9682 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9683 ;; We move the back-chain and decrement the stack pointer.
9685 (define_expand "allocate_stack"
9686   [(set (match_operand 0 "gpc_reg_operand" "")
9687         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9688    (set (reg 1)
9689         (minus (reg 1) (match_dup 1)))]
9690   ""
9691   "
9692 { rtx chain = gen_reg_rtx (Pmode);
9693   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9694   rtx neg_op0;
9695   rtx insn, par, set, mem;
9697   emit_move_insn (chain, stack_bot);
9699   /* Check stack bounds if necessary.  */
9700   if (crtl->limit_stack)
9701     {
9702       rtx available;
9703       available = expand_binop (Pmode, sub_optab,
9704                                 stack_pointer_rtx, stack_limit_rtx,
9705                                 NULL_RTX, 1, OPTAB_WIDEN);
9706       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9707     }
9709   if (GET_CODE (operands[1]) != CONST_INT
9710       || INTVAL (operands[1]) < -32767
9711       || INTVAL (operands[1]) > 32768)
9712     {
9713       neg_op0 = gen_reg_rtx (Pmode);
9714       if (TARGET_32BIT)
9715         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9716       else
9717         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9718     }
9719   else
9720     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9722   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9723                                        : gen_movdi_di_update_stack))
9724                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9725                          chain));
9726   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9727      it now and set the alias set/attributes. The above gen_*_update
9728      calls will generate a PARALLEL with the MEM set being the first
9729      operation. */
9730   par = PATTERN (insn);
9731   gcc_assert (GET_CODE (par) == PARALLEL);
9732   set = XVECEXP (par, 0, 0);
9733   gcc_assert (GET_CODE (set) == SET);
9734   mem = SET_DEST (set);
9735   gcc_assert (MEM_P (mem));
9736   MEM_NOTRAP_P (mem) = 1;
9737   set_mem_alias_set (mem, get_frame_alias_set ());
9739   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9740   DONE;
9743 ;; These patterns say how to save and restore the stack pointer.  We need not
9744 ;; save the stack pointer at function level since we are careful to
9745 ;; preserve the backchain.  At block level, we have to restore the backchain
9746 ;; when we restore the stack pointer.
9748 ;; For nonlocal gotos, we must save both the stack pointer and its
9749 ;; backchain and restore both.  Note that in the nonlocal case, the
9750 ;; save area is a memory location.
9752 (define_expand "save_stack_function"
9753   [(match_operand 0 "any_operand" "")
9754    (match_operand 1 "any_operand" "")]
9755   ""
9756   "DONE;")
9758 (define_expand "restore_stack_function"
9759   [(match_operand 0 "any_operand" "")
9760    (match_operand 1 "any_operand" "")]
9761   ""
9762   "DONE;")
9764 ;; Adjust stack pointer (op0) to a new value (op1).
9765 ;; First copy old stack backchain to new location, and ensure that the
9766 ;; scheduler won't reorder the sp assignment before the backchain write.
9767 (define_expand "restore_stack_block"
9768   [(set (match_dup 2) (match_dup 3))
9769    (set (match_dup 4) (match_dup 2))
9770    (match_dup 5)
9771    (set (match_operand 0 "register_operand" "")
9772         (match_operand 1 "register_operand" ""))]
9773   ""
9774   "
9776   rtvec p;
9778   operands[1] = force_reg (Pmode, operands[1]);
9779   operands[2] = gen_reg_rtx (Pmode);
9780   operands[3] = gen_frame_mem (Pmode, operands[0]);
9781   operands[4] = gen_frame_mem (Pmode, operands[1]);
9782   p = rtvec_alloc (1);
9783   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9784                                   const0_rtx);
9785   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9788 (define_expand "save_stack_nonlocal"
9789   [(set (match_dup 3) (match_dup 4))
9790    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9791    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9792   ""
9793   "
9795   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9797   /* Copy the backchain to the first word, sp to the second.  */
9798   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9799   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9800   operands[3] = gen_reg_rtx (Pmode);
9801   operands[4] = gen_frame_mem (Pmode, operands[1]);
9804 (define_expand "restore_stack_nonlocal"
9805   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9806    (set (match_dup 3) (match_dup 4))
9807    (set (match_dup 5) (match_dup 2))
9808    (match_dup 6)
9809    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9810   ""
9811   "
9813   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9814   rtvec p;
9816   /* Restore the backchain from the first word, sp from the second.  */
9817   operands[2] = gen_reg_rtx (Pmode);
9818   operands[3] = gen_reg_rtx (Pmode);
9819   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9820   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9821   operands[5] = gen_frame_mem (Pmode, operands[3]);
9822   p = rtvec_alloc (1);
9823   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9824                                   const0_rtx);
9825   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9828 ;; TOC register handling.
9830 ;; Code to initialize the TOC register...
9832 (define_insn "load_toc_aix_si"
9833   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9834                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9835               (use (reg:SI 2))])]
9836   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9837   "*
9839   char buf[30];
9840   extern int need_toc_init;
9841   need_toc_init = 1;
9842   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9843   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9844   operands[2] = gen_rtx_REG (Pmode, 2);
9845   return \"lwz %0,%1(%2)\";
9847   [(set_attr "type" "load")
9848    (set_attr "update" "no")
9849    (set_attr "indexed" "no")])
9851 (define_insn "load_toc_aix_di"
9852   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9853                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9854               (use (reg:DI 2))])]
9855   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9856   "*
9858   char buf[30];
9859   extern int need_toc_init;
9860   need_toc_init = 1;
9861   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9862                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9863   if (TARGET_ELF)
9864     strcat (buf, \"@toc\");
9865   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9866   operands[2] = gen_rtx_REG (Pmode, 2);
9867   return \"ld %0,%1(%2)\";
9869   [(set_attr "type" "load")
9870    (set_attr "update" "no")
9871    (set_attr "indexed" "no")])
9873 (define_insn "load_toc_v4_pic_si"
9874   [(set (reg:SI LR_REGNO)
9875         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9876   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9877   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9878   [(set_attr "type" "branch")
9879    (set_attr "length" "4")])
9881 (define_expand "load_toc_v4_PIC_1"
9882   [(parallel [(set (reg:SI LR_REGNO)
9883                    (match_operand:SI 0 "immediate_operand" "s"))
9884               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9885   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9886    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9887   "")
9889 (define_insn "load_toc_v4_PIC_1_normal"
9890   [(set (reg:SI LR_REGNO)
9891         (match_operand:SI 0 "immediate_operand" "s"))
9892    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9893   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9894    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9895   "bcl 20,31,%0\\n%0:"
9896   [(set_attr "type" "branch")
9897    (set_attr "length" "4")
9898    (set_attr "cannot_copy" "yes")])
9900 (define_insn "load_toc_v4_PIC_1_476"
9901   [(set (reg:SI LR_REGNO)
9902         (match_operand:SI 0 "immediate_operand" "s"))
9903    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9904   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9905    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9906   "*
9908   char name[32];
9909   static char templ[32];
9911   get_ppc476_thunk_name (name);
9912   sprintf (templ, \"bl %s\\n%%0:\", name);
9913   return templ;
9915   [(set_attr "type" "branch")
9916    (set_attr "length" "4")
9917    (set_attr "cannot_copy" "yes")])
9919 (define_expand "load_toc_v4_PIC_1b"
9920   [(parallel [(set (reg:SI LR_REGNO)
9921                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9922                                (label_ref (match_operand 1 "" ""))]
9923                            UNSPEC_TOCPTR))
9924               (match_dup 1)])]
9925   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9926   "")
9928 (define_insn "load_toc_v4_PIC_1b_normal"
9929   [(set (reg:SI LR_REGNO)
9930         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9931                     (label_ref (match_operand 1 "" ""))]
9932                 UNSPEC_TOCPTR))
9933    (match_dup 1)]
9934   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9935   "bcl 20,31,$+8\;.long %0-$"
9936   [(set_attr "type" "branch")
9937    (set_attr "length" "8")])
9939 (define_insn "load_toc_v4_PIC_1b_476"
9940   [(set (reg:SI LR_REGNO)
9941         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9942                     (label_ref (match_operand 1 "" ""))]
9943                 UNSPEC_TOCPTR))
9944    (match_dup 1)]
9945   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9946   "*
9948   char name[32];
9949   static char templ[32];
9951   get_ppc476_thunk_name (name);
9952   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9953   return templ;
9955   [(set_attr "type" "branch")
9956    (set_attr "length" "16")])
9958 (define_insn "load_toc_v4_PIC_2"
9959   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9960         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9961                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9962                              (match_operand:SI 3 "immediate_operand" "s")))))]
9963   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9964   "lwz %0,%2-%3(%1)"
9965   [(set_attr "type" "load")])
9967 (define_insn "load_toc_v4_PIC_3b"
9968   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9969         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9970                  (high:SI
9971                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9972                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9973   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9974   "addis %0,%1,%2-%3@ha")
9976 (define_insn "load_toc_v4_PIC_3c"
9977   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9978         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9979                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9980                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9981   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9982   "addi %0,%1,%2-%3@l")
9984 ;; If the TOC is shared over a translation unit, as happens with all
9985 ;; the kinds of PIC that we support, we need to restore the TOC
9986 ;; pointer only when jumping over units of translation.
9987 ;; On Darwin, we need to reload the picbase.
9989 (define_expand "builtin_setjmp_receiver"
9990   [(use (label_ref (match_operand 0 "" "")))]
9991   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9992    || (TARGET_TOC && TARGET_MINIMAL_TOC)
9993    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9994   "
9996 #if TARGET_MACHO
9997   if (DEFAULT_ABI == ABI_DARWIN)
9998     {
9999       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10000       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10001       rtx tmplabrtx;
10002       char tmplab[20];
10004       crtl->uses_pic_offset_table = 1;
10005       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10006                                   CODE_LABEL_NUMBER (operands[0]));
10007       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10009       emit_insn (gen_load_macho_picbase (tmplabrtx));
10010       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10011       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10012     }
10013   else
10014 #endif
10015     rs6000_emit_load_toc_table (FALSE);
10016   DONE;
10019 ;; Largetoc support
10020 (define_insn "*largetoc_high"
10021   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10022         (high:DI
10023           (unspec [(match_operand:DI 1 "" "")
10024                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10025                   UNSPEC_TOCREL)))]
10026    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10027    "addis %0,%2,%1@toc@ha")
10029 (define_insn "*largetoc_high_aix<mode>"
10030   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10031         (high:P
10032           (unspec [(match_operand:P 1 "" "")
10033                    (match_operand:P 2 "gpc_reg_operand" "b")]
10034                   UNSPEC_TOCREL)))]
10035    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10036    "addis %0,%1@u(%2)")
10038 (define_insn "*largetoc_high_plus"
10039   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10040         (high:DI
10041           (plus:DI
10042             (unspec [(match_operand:DI 1 "" "")
10043                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10044                     UNSPEC_TOCREL)
10045             (match_operand:DI 3 "add_cint_operand" "n"))))]
10046    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10047    "addis %0,%2,%1+%3@toc@ha")
10049 (define_insn "*largetoc_high_plus_aix<mode>"
10050   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10051         (high:P
10052           (plus:P
10053             (unspec [(match_operand:P 1 "" "")
10054                      (match_operand:P 2 "gpc_reg_operand" "b")]
10055                     UNSPEC_TOCREL)
10056             (match_operand:P 3 "add_cint_operand" "n"))))]
10057    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10058    "addis %0,%1+%3@u(%2)")
10060 (define_insn "*largetoc_low"
10061   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10062         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10063                    (match_operand:DI 2 "" "")))]
10064    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10065    "addi %0,%1,%2@l")
10067 (define_insn "*largetoc_low_aix<mode>"
10068   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10069         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10070                    (match_operand:P 2 "" "")))]
10071    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10072    "la %0,%2@l(%1)")
10074 (define_insn_and_split "*tocref<mode>"
10075   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10076         (match_operand:P 1 "small_toc_ref" "R"))]
10077    "TARGET_TOC"
10078    "la %0,%a1"
10079    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10080   [(set (match_dup 0) (high:P (match_dup 1)))
10081    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10083 ;; Elf specific ways of loading addresses for non-PIC code.
10084 ;; The output of this could be r0, but we make a very strong
10085 ;; preference for a base register because it will usually
10086 ;; be needed there.
10087 (define_insn "elf_high"
10088   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10089         (high:SI (match_operand 1 "" "")))]
10090   "TARGET_ELF && ! TARGET_64BIT"
10091   "lis %0,%1@ha")
10093 (define_insn "elf_low"
10094   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10095         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10096                    (match_operand 2 "" "")))]
10097    "TARGET_ELF && ! TARGET_64BIT"
10098    "la %0,%2@l(%1)")
10100 ;; Call and call_value insns
10101 (define_expand "call"
10102   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10103                     (match_operand 1 "" ""))
10104               (use (match_operand 2 "" ""))
10105               (clobber (reg:SI LR_REGNO))])]
10106   ""
10107   "
10109 #if TARGET_MACHO
10110   if (MACHOPIC_INDIRECT)
10111     operands[0] = machopic_indirect_call_target (operands[0]);
10112 #endif
10114   gcc_assert (GET_CODE (operands[0]) == MEM);
10115   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10117   operands[0] = XEXP (operands[0], 0);
10119   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10120     {
10121       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10122       DONE;
10123     }
10125   if (GET_CODE (operands[0]) != SYMBOL_REF
10126       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10127     {
10128       if (INTVAL (operands[2]) & CALL_LONG)
10129         operands[0] = rs6000_longcall_ref (operands[0]);
10131       switch (DEFAULT_ABI)
10132         {
10133         case ABI_V4:
10134         case ABI_DARWIN:
10135           operands[0] = force_reg (Pmode, operands[0]);
10136           break;
10138         default:
10139           gcc_unreachable ();
10140         }
10141     }
10144 (define_expand "call_value"
10145   [(parallel [(set (match_operand 0 "" "")
10146                    (call (mem:SI (match_operand 1 "address_operand" ""))
10147                          (match_operand 2 "" "")))
10148               (use (match_operand 3 "" ""))
10149               (clobber (reg:SI LR_REGNO))])]
10150   ""
10151   "
10153 #if TARGET_MACHO
10154   if (MACHOPIC_INDIRECT)
10155     operands[1] = machopic_indirect_call_target (operands[1]);
10156 #endif
10158   gcc_assert (GET_CODE (operands[1]) == MEM);
10159   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10161   operands[1] = XEXP (operands[1], 0);
10163   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10164     {
10165       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10166       DONE;
10167     }
10169   if (GET_CODE (operands[1]) != SYMBOL_REF
10170       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10171     {
10172       if (INTVAL (operands[3]) & CALL_LONG)
10173         operands[1] = rs6000_longcall_ref (operands[1]);
10175       switch (DEFAULT_ABI)
10176         {
10177         case ABI_V4:
10178         case ABI_DARWIN:
10179           operands[1] = force_reg (Pmode, operands[1]);
10180           break;
10182         default:
10183           gcc_unreachable ();
10184         }
10185     }
10188 ;; Call to function in current module.  No TOC pointer reload needed.
10189 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10190 ;; either the function was not prototyped, or it was prototyped as a
10191 ;; variable argument function.  It is > 0 if FP registers were passed
10192 ;; and < 0 if they were not.
10194 (define_insn "*call_local32"
10195   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10196          (match_operand 1 "" "g,g"))
10197    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10198    (clobber (reg:SI LR_REGNO))]
10199   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10200   "*
10202   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10203     output_asm_insn (\"crxor 6,6,6\", operands);
10205   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10206     output_asm_insn (\"creqv 6,6,6\", operands);
10208   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10210   [(set_attr "type" "branch")
10211    (set_attr "length" "4,8")])
10213 (define_insn "*call_local64"
10214   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10215          (match_operand 1 "" "g,g"))
10216    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10217    (clobber (reg:SI LR_REGNO))]
10218   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10219   "*
10221   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10222     output_asm_insn (\"crxor 6,6,6\", operands);
10224   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10225     output_asm_insn (\"creqv 6,6,6\", operands);
10227   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10229   [(set_attr "type" "branch")
10230    (set_attr "length" "4,8")])
10232 (define_insn "*call_value_local32"
10233   [(set (match_operand 0 "" "")
10234         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10235               (match_operand 2 "" "g,g")))
10236    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10237    (clobber (reg:SI LR_REGNO))]
10238   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10239   "*
10241   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10242     output_asm_insn (\"crxor 6,6,6\", operands);
10244   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10245     output_asm_insn (\"creqv 6,6,6\", operands);
10247   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10249   [(set_attr "type" "branch")
10250    (set_attr "length" "4,8")])
10253 (define_insn "*call_value_local64"
10254   [(set (match_operand 0 "" "")
10255         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10256               (match_operand 2 "" "g,g")))
10257    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10258    (clobber (reg:SI LR_REGNO))]
10259   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10260   "*
10262   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10263     output_asm_insn (\"crxor 6,6,6\", operands);
10265   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10266     output_asm_insn (\"creqv 6,6,6\", operands);
10268   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10270   [(set_attr "type" "branch")
10271    (set_attr "length" "4,8")])
10274 ;; A function pointer under System V is just a normal pointer
10275 ;; operands[0] is the function pointer
10276 ;; operands[1] is the stack size to clean up
10277 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10278 ;; which indicates how to set cr1
10280 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10281   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10282          (match_operand 1 "" "g,g,g,g"))
10283    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10284    (clobber (reg:SI LR_REGNO))]
10285   "DEFAULT_ABI == ABI_V4
10286    || DEFAULT_ABI == ABI_DARWIN"
10288   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10289     output_asm_insn ("crxor 6,6,6", operands);
10291   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10292     output_asm_insn ("creqv 6,6,6", operands);
10294   return "b%T0l";
10296   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10297    (set_attr "length" "4,4,8,8")])
10299 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10300   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10301          (match_operand 1 "" "g,g"))
10302    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10303    (clobber (reg:SI LR_REGNO))]
10304   "(DEFAULT_ABI == ABI_DARWIN
10305    || (DEFAULT_ABI == ABI_V4
10306        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10308   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10309     output_asm_insn ("crxor 6,6,6", operands);
10311   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10312     output_asm_insn ("creqv 6,6,6", operands);
10314 #if TARGET_MACHO
10315   return output_call(insn, operands, 0, 2);
10316 #else
10317   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10318     {
10319       gcc_assert (!TARGET_SECURE_PLT);
10320       return "bl %z0@plt";
10321     }
10322   else
10323     return "bl %z0";
10324 #endif
10326   "DEFAULT_ABI == ABI_V4
10327    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10328    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10329   [(parallel [(call (mem:SI (match_dup 0))
10330                     (match_dup 1))
10331               (use (match_dup 2))
10332               (use (match_dup 3))
10333               (clobber (reg:SI LR_REGNO))])]
10335   operands[3] = pic_offset_table_rtx;
10337   [(set_attr "type" "branch,branch")
10338    (set_attr "length" "4,8")])
10340 (define_insn "*call_nonlocal_sysv_secure<mode>"
10341   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10342          (match_operand 1 "" "g,g"))
10343    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10344    (use (match_operand:SI 3 "register_operand" "r,r"))
10345    (clobber (reg:SI LR_REGNO))]
10346   "(DEFAULT_ABI == ABI_V4
10347     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10348     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10350   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10351     output_asm_insn ("crxor 6,6,6", operands);
10353   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10354     output_asm_insn ("creqv 6,6,6", operands);
10356   if (flag_pic == 2)
10357     /* The magic 32768 offset here and in the other sysv call insns
10358        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10359        See sysv4.h:toc_section.  */
10360     return "bl %z0+32768@plt";
10361   else
10362     return "bl %z0@plt";
10364   [(set_attr "type" "branch,branch")
10365    (set_attr "length" "4,8")])
10367 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10368   [(set (match_operand 0 "" "")
10369         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10370               (match_operand 2 "" "g,g,g,g")))
10371    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10372    (clobber (reg:SI LR_REGNO))]
10373   "DEFAULT_ABI == ABI_V4
10374    || DEFAULT_ABI == ABI_DARWIN"
10376   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10377     output_asm_insn ("crxor 6,6,6", operands);
10379   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10380     output_asm_insn ("creqv 6,6,6", operands);
10382   return "b%T1l";
10384   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10385    (set_attr "length" "4,4,8,8")])
10387 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10388   [(set (match_operand 0 "" "")
10389         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10390               (match_operand 2 "" "g,g")))
10391    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10392    (clobber (reg:SI LR_REGNO))]
10393   "(DEFAULT_ABI == ABI_DARWIN
10394    || (DEFAULT_ABI == ABI_V4
10395        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10397   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10398     output_asm_insn ("crxor 6,6,6", operands);
10400   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10401     output_asm_insn ("creqv 6,6,6", operands);
10403 #if TARGET_MACHO
10404   return output_call(insn, operands, 1, 3);
10405 #else
10406   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10407     {
10408       gcc_assert (!TARGET_SECURE_PLT);
10409       return "bl %z1@plt";
10410     }
10411   else
10412     return "bl %z1";
10413 #endif
10415   "DEFAULT_ABI == ABI_V4
10416    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10417    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10418   [(parallel [(set (match_dup 0)
10419                    (call (mem:SI (match_dup 1))
10420                          (match_dup 2)))
10421               (use (match_dup 3))
10422               (use (match_dup 4))
10423               (clobber (reg:SI LR_REGNO))])]
10425   operands[4] = pic_offset_table_rtx;
10427   [(set_attr "type" "branch,branch")
10428    (set_attr "length" "4,8")])
10430 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10431   [(set (match_operand 0 "" "")
10432         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10433               (match_operand 2 "" "g,g")))
10434    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10435    (use (match_operand:SI 4 "register_operand" "r,r"))
10436    (clobber (reg:SI LR_REGNO))]
10437   "(DEFAULT_ABI == ABI_V4
10438     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10439     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10441   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10442     output_asm_insn ("crxor 6,6,6", operands);
10444   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10445     output_asm_insn ("creqv 6,6,6", operands);
10447   if (flag_pic == 2)
10448     return "bl %z1+32768@plt";
10449   else
10450     return "bl %z1@plt";
10452   [(set_attr "type" "branch,branch")
10453    (set_attr "length" "4,8")])
10456 ;; Call to AIX abi function in the same module.
10458 (define_insn "*call_local_aix<mode>"
10459   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10460          (match_operand 1 "" "g"))
10461    (clobber (reg:P LR_REGNO))]
10462   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10463   "bl %z0"
10464   [(set_attr "type" "branch")
10465    (set_attr "length" "4")])
10467 (define_insn "*call_value_local_aix<mode>"
10468   [(set (match_operand 0 "" "")
10469         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10470               (match_operand 2 "" "g")))
10471    (clobber (reg:P LR_REGNO))]
10472   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10473   "bl %z1"
10474   [(set_attr "type" "branch")
10475    (set_attr "length" "4")])
10477 ;; Call to AIX abi function which may be in another module.
10478 ;; Restore the TOC pointer (r2) after the call.
10480 (define_insn "*call_nonlocal_aix<mode>"
10481   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10482          (match_operand 1 "" "g"))
10483    (clobber (reg:P LR_REGNO))]
10484   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10485   "bl %z0\;nop"
10486   [(set_attr "type" "branch")
10487    (set_attr "length" "8")])
10489 (define_insn "*call_value_nonlocal_aix<mode>"
10490   [(set (match_operand 0 "" "")
10491         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10492               (match_operand 2 "" "g")))
10493    (clobber (reg:P LR_REGNO))]
10494   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10495   "bl %z1\;nop"
10496   [(set_attr "type" "branch")
10497    (set_attr "length" "8")])
10499 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10500 ;; Operand0 is the addresss of the function to call
10501 ;; Operand2 is the location in the function descriptor to load r2 from
10502 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10504 (define_insn "*call_indirect_aix<mode>"
10505   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10506          (match_operand 1 "" "g,g"))
10507    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10508    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10509    (clobber (reg:P LR_REGNO))]
10510   "DEFAULT_ABI == ABI_AIX"
10511   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10512   [(set_attr "type" "jmpreg")
10513    (set_attr "length" "12")])
10515 (define_insn "*call_value_indirect_aix<mode>"
10516   [(set (match_operand 0 "" "")
10517         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10518               (match_operand 2 "" "g,g")))
10519    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10520    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10521    (clobber (reg:P LR_REGNO))]
10522   "DEFAULT_ABI == ABI_AIX"
10523   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10524   [(set_attr "type" "jmpreg")
10525    (set_attr "length" "12")])
10527 ;; Call to indirect functions with the ELFv2 ABI.
10528 ;; Operand0 is the addresss of the function to call
10529 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10531 (define_insn "*call_indirect_elfv2<mode>"
10532   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10533          (match_operand 1 "" "g,g"))
10534    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10535    (clobber (reg:P LR_REGNO))]
10536   "DEFAULT_ABI == ABI_ELFv2"
10537   "b%T0l\;<ptrload> 2,%2(1)"
10538   [(set_attr "type" "jmpreg")
10539    (set_attr "length" "8")])
10541 (define_insn "*call_value_indirect_elfv2<mode>"
10542   [(set (match_operand 0 "" "")
10543         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10544               (match_operand 2 "" "g,g")))
10545    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10546    (clobber (reg:P LR_REGNO))]
10547   "DEFAULT_ABI == ABI_ELFv2"
10548   "b%T1l\;<ptrload> 2,%3(1)"
10549   [(set_attr "type" "jmpreg")
10550    (set_attr "length" "8")])
10553 ;; Call subroutine returning any type.
10554 (define_expand "untyped_call"
10555   [(parallel [(call (match_operand 0 "" "")
10556                     (const_int 0))
10557               (match_operand 1 "" "")
10558               (match_operand 2 "" "")])]
10559   ""
10560   "
10562   int i;
10564   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10566   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10567     {
10568       rtx set = XVECEXP (operands[2], 0, i);
10569       emit_move_insn (SET_DEST (set), SET_SRC (set));
10570     }
10572   /* The optimizer does not know that the call sets the function value
10573      registers we stored in the result block.  We avoid problems by
10574      claiming that all hard registers are used and clobbered at this
10575      point.  */
10576   emit_insn (gen_blockage ());
10578   DONE;
10581 ;; sibling call patterns
10582 (define_expand "sibcall"
10583   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10584                     (match_operand 1 "" ""))
10585               (use (match_operand 2 "" ""))
10586               (simple_return)])]
10587   ""
10588   "
10590 #if TARGET_MACHO
10591   if (MACHOPIC_INDIRECT)
10592     operands[0] = machopic_indirect_call_target (operands[0]);
10593 #endif
10595   gcc_assert (GET_CODE (operands[0]) == MEM);
10596   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10598   operands[0] = XEXP (operands[0], 0);
10600   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10601     {
10602       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10603       DONE;
10604     }
10607 (define_expand "sibcall_value"
10608   [(parallel [(set (match_operand 0 "register_operand" "")
10609                 (call (mem:SI (match_operand 1 "address_operand" ""))
10610                       (match_operand 2 "" "")))
10611               (use (match_operand 3 "" ""))
10612               (simple_return)])]
10613   ""
10614   "
10616 #if TARGET_MACHO
10617   if (MACHOPIC_INDIRECT)
10618     operands[1] = machopic_indirect_call_target (operands[1]);
10619 #endif
10621   gcc_assert (GET_CODE (operands[1]) == MEM);
10622   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10624   operands[1] = XEXP (operands[1], 0);
10626   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10627     {
10628       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10629       DONE;
10630     }
10633 (define_insn "*sibcall_local32"
10634   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10635          (match_operand 1 "" "g,g"))
10636    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10637    (simple_return)]
10638   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10639   "*
10641   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10642     output_asm_insn (\"crxor 6,6,6\", operands);
10644   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10645     output_asm_insn (\"creqv 6,6,6\", operands);
10647   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10649   [(set_attr "type" "branch")
10650    (set_attr "length" "4,8")])
10652 (define_insn "*sibcall_local64"
10653   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10654          (match_operand 1 "" "g,g"))
10655    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10656    (simple_return)]
10657   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10658   "*
10660   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10661     output_asm_insn (\"crxor 6,6,6\", operands);
10663   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10664     output_asm_insn (\"creqv 6,6,6\", operands);
10666   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10668   [(set_attr "type" "branch")
10669    (set_attr "length" "4,8")])
10671 (define_insn "*sibcall_value_local32"
10672   [(set (match_operand 0 "" "")
10673         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10674               (match_operand 2 "" "g,g")))
10675    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10676    (simple_return)]
10677   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10678   "*
10680   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10681     output_asm_insn (\"crxor 6,6,6\", operands);
10683   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10684     output_asm_insn (\"creqv 6,6,6\", operands);
10686   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10688   [(set_attr "type" "branch")
10689    (set_attr "length" "4,8")])
10691 (define_insn "*sibcall_value_local64"
10692   [(set (match_operand 0 "" "")
10693         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10694               (match_operand 2 "" "g,g")))
10695    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10696    (simple_return)]
10697   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10698   "*
10700   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10701     output_asm_insn (\"crxor 6,6,6\", operands);
10703   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10704     output_asm_insn (\"creqv 6,6,6\", operands);
10706   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10708   [(set_attr "type" "branch")
10709    (set_attr "length" "4,8")])
10711 (define_insn "*sibcall_nonlocal_sysv<mode>"
10712   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10713          (match_operand 1 "" ""))
10714    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10715    (simple_return)]
10716   "(DEFAULT_ABI == ABI_DARWIN
10717     || DEFAULT_ABI == ABI_V4)
10718    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10719   "*
10721   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10722     output_asm_insn (\"crxor 6,6,6\", operands);
10724   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10725     output_asm_insn (\"creqv 6,6,6\", operands);
10727   if (which_alternative >= 2)
10728     return \"b%T0\";
10729   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10730     {
10731       gcc_assert (!TARGET_SECURE_PLT);
10732       return \"b %z0@plt\";
10733     }
10734   else
10735     return \"b %z0\";
10737   [(set_attr "type" "branch")
10738    (set_attr "length" "4,8,4,8")])
10740 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10741   [(set (match_operand 0 "" "")
10742         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10743               (match_operand 2 "" "")))
10744    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10745    (simple_return)]
10746   "(DEFAULT_ABI == ABI_DARWIN
10747     || DEFAULT_ABI == ABI_V4)
10748    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10749   "*
10751   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10752     output_asm_insn (\"crxor 6,6,6\", operands);
10754   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10755     output_asm_insn (\"creqv 6,6,6\", operands);
10757   if (which_alternative >= 2)
10758     return \"b%T1\";
10759   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10760     {
10761       gcc_assert (!TARGET_SECURE_PLT);
10762       return \"b %z1@plt\";
10763     }
10764   else
10765     return \"b %z1\";
10767   [(set_attr "type" "branch")
10768    (set_attr "length" "4,8,4,8")])
10770 ;; AIX ABI sibling call patterns.
10772 (define_insn "*sibcall_aix<mode>"
10773   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10774          (match_operand 1 "" "g,g"))
10775    (simple_return)]
10776   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10777   "@
10778    b %z0
10779    b%T0"
10780   [(set_attr "type" "branch")
10781    (set_attr "length" "4")])
10783 (define_insn "*sibcall_value_aix<mode>"
10784   [(set (match_operand 0 "" "")
10785         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10786               (match_operand 2 "" "g,g")))
10787    (simple_return)]
10788   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10789   "@
10790    b %z1
10791    b%T1"
10792   [(set_attr "type" "branch")
10793    (set_attr "length" "4")])
10795 (define_expand "sibcall_epilogue"
10796   [(use (const_int 0))]
10797   ""
10799   if (!TARGET_SCHED_PROLOG)
10800     emit_insn (gen_blockage ());
10801   rs6000_emit_epilogue (TRUE);
10802   DONE;
10805 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10806 ;; all of memory.  This blocks insns from being moved across this point.
10808 (define_insn "blockage"
10809   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10810   ""
10811   "")
10813 (define_expand "probe_stack_address"
10814   [(use (match_operand 0 "address_operand"))]
10815   ""
10817   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10818   MEM_VOLATILE_P (operands[0]) = 1;
10820   if (TARGET_64BIT)
10821     emit_insn (gen_probe_stack_di (operands[0]));
10822   else
10823     emit_insn (gen_probe_stack_si (operands[0]));
10824   DONE;
10827 (define_insn "probe_stack_<mode>"
10828   [(set (match_operand:P 0 "memory_operand" "=m")
10829         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10830   ""
10832   operands[1] = gen_rtx_REG (Pmode, 0);
10833   return "st<wd>%U0%X0 %1,%0";
10835   [(set_attr "type" "store")
10836    (set (attr "update")
10837         (if_then_else (match_operand 0 "update_address_mem")
10838                       (const_string "yes")
10839                       (const_string "no")))
10840    (set (attr "indexed")
10841         (if_then_else (match_operand 0 "indexed_address_mem")
10842                       (const_string "yes")
10843                       (const_string "no")))
10844    (set_attr "length" "4")])
10846 (define_insn "probe_stack_range<P:mode>"
10847   [(set (match_operand:P 0 "register_operand" "=r")
10848         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10849                             (match_operand:P 2 "register_operand" "r")]
10850                            UNSPECV_PROBE_STACK_RANGE))]
10851   ""
10852   "* return output_probe_stack_range (operands[0], operands[2]);"
10853   [(set_attr "type" "three")])
10855 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10856 ;; signed & unsigned, and one type of branch.
10858 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10859 ;; insns, and branches.
10861 (define_expand "cbranch<mode>4"
10862   [(use (match_operator 0 "rs6000_cbranch_operator"
10863          [(match_operand:GPR 1 "gpc_reg_operand" "")
10864           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10865    (use (match_operand 3 ""))]
10866   ""
10867   "
10869   /* Take care of the possibility that operands[2] might be negative but
10870      this might be a logical operation.  That insn doesn't exist.  */
10871   if (GET_CODE (operands[2]) == CONST_INT
10872       && INTVAL (operands[2]) < 0)
10873     {
10874       operands[2] = force_reg (<MODE>mode, operands[2]);
10875       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10876                                     GET_MODE (operands[0]),
10877                                     operands[1], operands[2]);
10878    }
10880   rs6000_emit_cbranch (<MODE>mode, operands);
10881   DONE;
10884 (define_expand "cbranch<mode>4"
10885   [(use (match_operator 0 "rs6000_cbranch_operator"
10886          [(match_operand:FP 1 "gpc_reg_operand" "")
10887           (match_operand:FP 2 "gpc_reg_operand" "")]))
10888    (use (match_operand 3 ""))]
10889   ""
10890   "
10892   rs6000_emit_cbranch (<MODE>mode, operands);
10893   DONE;
10896 (define_expand "cstore<mode>4_signed"
10897   [(use (match_operator 1 "signed_comparison_operator"
10898          [(match_operand:P 2 "gpc_reg_operand")
10899           (match_operand:P 3 "gpc_reg_operand")]))
10900    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10901   ""
10903   enum rtx_code cond_code = GET_CODE (operands[1]);
10905   rtx op0 = operands[0];
10906   rtx op1 = operands[2];
10907   rtx op2 = operands[3];
10909   if (cond_code == GE || cond_code == LT)
10910     {
10911       cond_code = swap_condition (cond_code);
10912       std::swap (op1, op2);
10913     }
10915   rtx tmp1 = gen_reg_rtx (<MODE>mode);
10916   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10917   rtx tmp3 = gen_reg_rtx (<MODE>mode);
10919   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10920   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10921   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10923   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10925   if (cond_code == LE)
10926     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10927   else
10928     {
10929       rtx tmp4 = gen_reg_rtx (<MODE>mode);
10930       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10931       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10932     }
10934   DONE;
10937 (define_expand "cstore<mode>4_unsigned"
10938   [(use (match_operator 1 "unsigned_comparison_operator"
10939          [(match_operand:P 2 "gpc_reg_operand")
10940           (match_operand:P 3 "reg_or_short_operand")]))
10941    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10942   ""
10944   enum rtx_code cond_code = GET_CODE (operands[1]);
10946   rtx op0 = operands[0];
10947   rtx op1 = operands[2];
10948   rtx op2 = operands[3];
10950   if (cond_code == GEU || cond_code == LTU)
10951     {
10952       cond_code = swap_condition (cond_code);
10953       std::swap (op1, op2);
10954     }
10956   if (!gpc_reg_operand (op1, <MODE>mode))
10957     op1 = force_reg (<MODE>mode, op1);
10958   if (!reg_or_short_operand (op2, <MODE>mode))
10959     op2 = force_reg (<MODE>mode, op2);
10961   rtx tmp = gen_reg_rtx (<MODE>mode);
10962   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10964   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10965   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10967   if (cond_code == LEU)
10968     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10969   else
10970     emit_insn (gen_neg<mode>2 (op0, tmp2));
10972   DONE;
10975 (define_expand "cstore_si_as_di"
10976   [(use (match_operator 1 "unsigned_comparison_operator"
10977          [(match_operand:SI 2 "gpc_reg_operand")
10978           (match_operand:SI 3 "reg_or_short_operand")]))
10979    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10980   ""
10982   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10983   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10985   operands[2] = force_reg (SImode, operands[2]);
10986   operands[3] = force_reg (SImode, operands[3]);
10987   rtx op1 = gen_reg_rtx (DImode);
10988   rtx op2 = gen_reg_rtx (DImode);
10989   convert_move (op1, operands[2], uns_flag);
10990   convert_move (op2, operands[3], uns_flag);
10992   if (cond_code == GT || cond_code == LE)
10993     {
10994       cond_code = swap_condition (cond_code);
10995       std::swap (op1, op2);
10996     }
10998   rtx tmp = gen_reg_rtx (DImode);
10999   rtx tmp2 = gen_reg_rtx (DImode);
11000   emit_insn (gen_subdi3 (tmp, op1, op2));
11001   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11003   rtx tmp3;
11004   switch (cond_code)
11005     {
11006     default:
11007       gcc_unreachable ();
11008     case LT:
11009       tmp3 = tmp2;
11010       break;
11011     case GE:
11012       tmp3 = gen_reg_rtx (DImode);
11013       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11014       break;
11015     }
11017   convert_move (operands[0], tmp3, 1);
11019   DONE;
11022 (define_expand "cstore<mode>4_signed_imm"
11023   [(use (match_operator 1 "signed_comparison_operator"
11024          [(match_operand:GPR 2 "gpc_reg_operand")
11025           (match_operand:GPR 3 "immediate_operand")]))
11026    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11027   ""
11029   bool invert = false;
11031   enum rtx_code cond_code = GET_CODE (operands[1]);
11033   rtx op0 = operands[0];
11034   rtx op1 = operands[2];
11035   HOST_WIDE_INT val = INTVAL (operands[3]);
11037   if (cond_code == GE || cond_code == GT)
11038     {
11039       cond_code = reverse_condition (cond_code);
11040       invert = true;
11041     }
11043   if (cond_code == LE)
11044     val++;
11046   rtx tmp = gen_reg_rtx (<MODE>mode);
11047   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11048   rtx x = gen_reg_rtx (<MODE>mode);
11049   if (val < 0)
11050     emit_insn (gen_and<mode>3 (x, op1, tmp));
11051   else
11052     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11054   if (invert)
11055     {
11056       rtx tmp = gen_reg_rtx (<MODE>mode);
11057       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11058       x = tmp;
11059     }
11061   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11062   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11064   DONE;
11067 (define_expand "cstore<mode>4_unsigned_imm"
11068   [(use (match_operator 1 "unsigned_comparison_operator"
11069          [(match_operand:GPR 2 "gpc_reg_operand")
11070           (match_operand:GPR 3 "immediate_operand")]))
11071    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11072   ""
11074   bool invert = false;
11076   enum rtx_code cond_code = GET_CODE (operands[1]);
11078   rtx op0 = operands[0];
11079   rtx op1 = operands[2];
11080   HOST_WIDE_INT val = INTVAL (operands[3]);
11082   if (cond_code == GEU || cond_code == GTU)
11083     {
11084       cond_code = reverse_condition (cond_code);
11085       invert = true;
11086     }
11088   if (cond_code == LEU)
11089     val++;
11091   rtx tmp = gen_reg_rtx (<MODE>mode);
11092   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11093   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11094   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11095   rtx x = gen_reg_rtx (<MODE>mode);
11096   if (val < 0)
11097     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11098   else
11099     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11101   if (invert)
11102     {
11103       rtx tmp = gen_reg_rtx (<MODE>mode);
11104       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11105       x = tmp;
11106     }
11108   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11109   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11111   DONE;
11114 (define_expand "cstore<mode>4"
11115   [(use (match_operator 1 "rs6000_cbranch_operator"
11116          [(match_operand:GPR 2 "gpc_reg_operand")
11117           (match_operand:GPR 3 "reg_or_short_operand")]))
11118    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11119   ""
11121   /* Use ISEL if the user asked for it.  */
11122   if (TARGET_ISEL)
11123     rs6000_emit_sISEL (<MODE>mode, operands);
11125   /* Expanding EQ and NE directly to some machine instructions does not help
11126      but does hurt combine.  So don't.  */
11127   else if (GET_CODE (operands[1]) == EQ)
11128     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11129   else if (<MODE>mode == Pmode
11130            && GET_CODE (operands[1]) == NE)
11131     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11132   else if (GET_CODE (operands[1]) == NE)
11133     {
11134       rtx tmp = gen_reg_rtx (<MODE>mode);
11135       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11136       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11137     }
11139   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11140      etc. combinations magically work out just right.  */
11141   else if (<MODE>mode == Pmode
11142            && unsigned_comparison_operator (operands[1], VOIDmode))
11143     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11144                                            operands[2], operands[3]));
11146   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11147   else if (<MODE>mode == SImode && Pmode == DImode)
11148     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11149                                     operands[2], operands[3]));
11151   /* For signed comparisons against a constant, we can do some simple
11152      bit-twiddling.  */
11153   else if (signed_comparison_operator (operands[1], VOIDmode)
11154            && CONST_INT_P (operands[3]))
11155     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11156                                              operands[2], operands[3]));
11158   /* And similarly for unsigned comparisons.  */
11159   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11160            && CONST_INT_P (operands[3]))
11161     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11162                                                operands[2], operands[3]));
11164   /* We also do not want to use mfcr for signed comparisons.  */
11165   else if (<MODE>mode == Pmode
11166            && signed_comparison_operator (operands[1], VOIDmode))
11167     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11168                                          operands[2], operands[3]));
11170   /* Everything else, use the mfcr brute force.  */
11171   else
11172     rs6000_emit_sCOND (<MODE>mode, operands);
11174   DONE;
11177 (define_expand "cstore<mode>4"
11178   [(use (match_operator 1 "rs6000_cbranch_operator"
11179          [(match_operand:FP 2 "gpc_reg_operand")
11180           (match_operand:FP 3 "gpc_reg_operand")]))
11181    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11182   ""
11184   rs6000_emit_sCOND (<MODE>mode, operands);
11185   DONE;
11189 (define_expand "stack_protect_set"
11190   [(match_operand 0 "memory_operand" "")
11191    (match_operand 1 "memory_operand" "")]
11192   ""
11194 #ifdef TARGET_THREAD_SSP_OFFSET
11195   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11196   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11197   operands[1] = gen_rtx_MEM (Pmode, addr);
11198 #endif
11199   if (TARGET_64BIT)
11200     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11201   else
11202     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11203   DONE;
11206 (define_insn "stack_protect_setsi"
11207   [(set (match_operand:SI 0 "memory_operand" "=m")
11208         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11209    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11210   "TARGET_32BIT"
11211   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11212   [(set_attr "type" "three")
11213    (set_attr "length" "12")])
11215 (define_insn "stack_protect_setdi"
11216   [(set (match_operand:DI 0 "memory_operand" "=Y")
11217         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11218    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11219   "TARGET_64BIT"
11220   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11221   [(set_attr "type" "three")
11222    (set_attr "length" "12")])
11224 (define_expand "stack_protect_test"
11225   [(match_operand 0 "memory_operand" "")
11226    (match_operand 1 "memory_operand" "")
11227    (match_operand 2 "" "")]
11228   ""
11230   rtx test, op0, op1;
11231 #ifdef TARGET_THREAD_SSP_OFFSET
11232   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11233   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11234   operands[1] = gen_rtx_MEM (Pmode, addr);
11235 #endif
11236   op0 = operands[0];
11237   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11238   test = gen_rtx_EQ (VOIDmode, op0, op1);
11239   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11240   DONE;
11243 (define_insn "stack_protect_testsi"
11244   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11245         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11246                       (match_operand:SI 2 "memory_operand" "m,m")]
11247                      UNSPEC_SP_TEST))
11248    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11249    (clobber (match_scratch:SI 3 "=&r,&r"))]
11250   "TARGET_32BIT"
11251   "@
11252    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11253    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11254   [(set_attr "length" "16,20")])
11256 (define_insn "stack_protect_testdi"
11257   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11258         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11259                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11260                      UNSPEC_SP_TEST))
11261    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11262    (clobber (match_scratch:DI 3 "=&r,&r"))]
11263   "TARGET_64BIT"
11264   "@
11265    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11266    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11267   [(set_attr "length" "16,20")])
11270 ;; Here are the actual compare insns.
11271 (define_insn "*cmp<mode>_signed"
11272   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11273         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11274                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11275   ""
11276   "cmp<wd>%I2 %0,%1,%2"
11277   [(set_attr "type" "cmp")])
11279 (define_insn "*cmp<mode>_unsigned"
11280   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11281         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11282                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11283   ""
11284   "cmpl<wd>%I2 %0,%1,%2"
11285   [(set_attr "type" "cmp")])
11287 ;; If we are comparing a register for equality with a large constant,
11288 ;; we can do this with an XOR followed by a compare.  But this is profitable
11289 ;; only if the large constant is only used for the comparison (and in this
11290 ;; case we already have a register to reuse as scratch).
11292 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11293 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11295 (define_peephole2
11296   [(set (match_operand:SI 0 "register_operand")
11297         (match_operand:SI 1 "logical_const_operand" ""))
11298    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11299                        [(match_dup 0)
11300                         (match_operand:SI 2 "logical_const_operand" "")]))
11301    (set (match_operand:CC 4 "cc_reg_operand" "")
11302         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11303                     (match_dup 0)))
11304    (set (pc)
11305         (if_then_else (match_operator 6 "equality_operator"
11306                        [(match_dup 4) (const_int 0)])
11307                       (match_operand 7 "" "")
11308                       (match_operand 8 "" "")))]
11309   "peep2_reg_dead_p (3, operands[0])
11310    && peep2_reg_dead_p (4, operands[4])
11311    && REGNO (operands[0]) != REGNO (operands[5])"
11312  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11313   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11314   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11317   /* Get the constant we are comparing against, and see what it looks like
11318      when sign-extended from 16 to 32 bits.  Then see what constant we could
11319      XOR with SEXTC to get the sign-extended value.  */
11320   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11321                                               SImode,
11322                                               operands[1], operands[2]);
11323   HOST_WIDE_INT c = INTVAL (cnst);
11324   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11325   HOST_WIDE_INT xorv = c ^ sextc;
11327   operands[9] = GEN_INT (xorv);
11328   operands[10] = GEN_INT (sextc);
11331 ;; The following two insns don't exist as single insns, but if we provide
11332 ;; them, we can swap an add and compare, which will enable us to overlap more
11333 ;; of the required delay between a compare and branch.  We generate code for
11334 ;; them by splitting.
11336 (define_insn ""
11337   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11338         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11339                     (match_operand:SI 2 "short_cint_operand" "i")))
11340    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11341         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11342   ""
11343   "#"
11344   [(set_attr "length" "8")])
11346 (define_insn ""
11347   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11348         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11349                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11350    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11351         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11352   ""
11353   "#"
11354   [(set_attr "length" "8")])
11356 (define_split
11357   [(set (match_operand:CC 3 "cc_reg_operand" "")
11358         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11359                     (match_operand:SI 2 "short_cint_operand" "")))
11360    (set (match_operand:SI 0 "gpc_reg_operand" "")
11361         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11362   ""
11363   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11364    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11366 (define_split
11367   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11368         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11369                        (match_operand:SI 2 "u_short_cint_operand" "")))
11370    (set (match_operand:SI 0 "gpc_reg_operand" "")
11371         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11372   ""
11373   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11374    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11376 ;; Only need to compare second words if first words equal
11377 (define_insn "*cmp<mode>_internal1"
11378   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11379         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11380                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11381   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11382    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11383   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11384   [(set_attr "type" "fpcompare")
11385    (set_attr "length" "12")])
11387 (define_insn_and_split "*cmp<mode>_internal2"
11388   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11389         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11390                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11391     (clobber (match_scratch:DF 3 "=d"))
11392     (clobber (match_scratch:DF 4 "=d"))
11393     (clobber (match_scratch:DF 5 "=d"))
11394     (clobber (match_scratch:DF 6 "=d"))
11395     (clobber (match_scratch:DF 7 "=d"))
11396     (clobber (match_scratch:DF 8 "=d"))
11397     (clobber (match_scratch:DF 9 "=d"))
11398     (clobber (match_scratch:DF 10 "=d"))
11399     (clobber (match_scratch:GPR 11 "=b"))]
11400   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11401    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11402   "#"
11403   "&& reload_completed"
11404   [(set (match_dup 3) (match_dup 14))
11405    (set (match_dup 4) (match_dup 15))
11406    (set (match_dup 9) (abs:DF (match_dup 5)))
11407    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11408    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11409                            (label_ref (match_dup 12))
11410                            (pc)))
11411    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11412    (set (pc) (label_ref (match_dup 13)))
11413    (match_dup 12)
11414    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11415    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11416    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11417    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11418    (match_dup 13)]
11420   REAL_VALUE_TYPE rv;
11421   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11422   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11424   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11425   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11426   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11427   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11428   operands[12] = gen_label_rtx ();
11429   operands[13] = gen_label_rtx ();
11430   real_inf (&rv);
11431   operands[14] = force_const_mem (DFmode,
11432                                   const_double_from_real_value (rv, DFmode));
11433   operands[15] = force_const_mem (DFmode,
11434                                   const_double_from_real_value (dconst0,
11435                                                                 DFmode));
11436   if (TARGET_TOC)
11437     {
11438       rtx tocref;
11439       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11440       operands[14] = gen_const_mem (DFmode, tocref);
11441       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11442       operands[15] = gen_const_mem (DFmode, tocref);
11443       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11444       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11445     }
11448 ;; Now we have the scc insns.  We can do some combinations because of the
11449 ;; way the machine works.
11451 ;; Note that this is probably faster if we can put an insn between the
11452 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11453 ;; cases the insns below which don't use an intermediate CR field will
11454 ;; be used instead.
11455 (define_insn ""
11456   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11457         (match_operator:SI 1 "scc_comparison_operator"
11458                            [(match_operand 2 "cc_reg_operand" "y")
11459                             (const_int 0)]))]
11460   ""
11461   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11462   [(set (attr "type")
11463      (cond [(match_test "TARGET_MFCRF")
11464                 (const_string "mfcrf")
11465            ]
11466         (const_string "mfcr")))
11467    (set_attr "length" "8")])
11469 ;; Same as above, but get the GT bit.
11470 (define_insn "move_from_CR_gt_bit"
11471   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11472         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11473   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11474   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11475   [(set_attr "type" "mfcr")
11476    (set_attr "length" "8")])
11478 ;; Same as above, but get the OV/ORDERED bit.
11479 (define_insn "move_from_CR_ov_bit"
11480   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11481         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11482                    UNSPEC_MV_CR_OV))]
11483   "TARGET_ISEL"
11484   "mfcr %0\;rlwinm %0,%0,%t1,1"
11485   [(set_attr "type" "mfcr")
11486    (set_attr "length" "8")])
11488 (define_insn ""
11489   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11490         (match_operator:DI 1 "scc_comparison_operator"
11491                            [(match_operand 2 "cc_reg_operand" "y")
11492                             (const_int 0)]))]
11493   "TARGET_POWERPC64"
11494   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11495   [(set (attr "type")
11496      (cond [(match_test "TARGET_MFCRF")
11497                 (const_string "mfcrf")
11498            ]
11499         (const_string "mfcr")))
11500    (set_attr "length" "8")])
11502 (define_insn ""
11503   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11504         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11505                                        [(match_operand 2 "cc_reg_operand" "y,y")
11506                                         (const_int 0)])
11507                     (const_int 0)))
11508    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11509         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11510   "TARGET_32BIT"
11511   "@
11512    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11513    #"
11514   [(set_attr "type" "shift")
11515    (set_attr "dot" "yes")
11516    (set_attr "length" "8,16")])
11518 (define_split
11519   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11520         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11521                                        [(match_operand 2 "cc_reg_operand" "")
11522                                         (const_int 0)])
11523                     (const_int 0)))
11524    (set (match_operand:SI 3 "gpc_reg_operand" "")
11525         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11526   "TARGET_32BIT && reload_completed"
11527   [(set (match_dup 3)
11528         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11529    (set (match_dup 0)
11530         (compare:CC (match_dup 3)
11531                     (const_int 0)))]
11532   "")
11534 (define_insn ""
11535   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11536         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11537                                       [(match_operand 2 "cc_reg_operand" "y")
11538                                        (const_int 0)])
11539                    (match_operand:SI 3 "const_int_operand" "n")))]
11540   ""
11541   "*
11543   int is_bit = ccr_bit (operands[1], 1);
11544   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11545   int count;
11547   if (is_bit >= put_bit)
11548     count = is_bit - put_bit;
11549   else
11550     count = 32 - (put_bit - is_bit);
11552   operands[4] = GEN_INT (count);
11553   operands[5] = GEN_INT (put_bit);
11555   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11557   [(set (attr "type")
11558      (cond [(match_test "TARGET_MFCRF")
11559                 (const_string "mfcrf")
11560            ]
11561         (const_string "mfcr")))
11562    (set_attr "length" "8")])
11564 (define_insn ""
11565   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11566         (compare:CC
11567          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11568                                        [(match_operand 2 "cc_reg_operand" "y,y")
11569                                         (const_int 0)])
11570                     (match_operand:SI 3 "const_int_operand" "n,n"))
11571          (const_int 0)))
11572    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11573         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11574                    (match_dup 3)))]
11575   ""
11576   "*
11578   int is_bit = ccr_bit (operands[1], 1);
11579   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11580   int count;
11582   /* Force split for non-cc0 compare.  */
11583   if (which_alternative == 1)
11584      return \"#\";
11586   if (is_bit >= put_bit)
11587     count = is_bit - put_bit;
11588   else
11589     count = 32 - (put_bit - is_bit);
11591   operands[5] = GEN_INT (count);
11592   operands[6] = GEN_INT (put_bit);
11594   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11596   [(set_attr "type" "shift")
11597    (set_attr "dot" "yes")
11598    (set_attr "length" "8,16")])
11600 (define_split
11601   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11602         (compare:CC
11603          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11604                                        [(match_operand 2 "cc_reg_operand" "")
11605                                         (const_int 0)])
11606                     (match_operand:SI 3 "const_int_operand" ""))
11607          (const_int 0)))
11608    (set (match_operand:SI 4 "gpc_reg_operand" "")
11609         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11610                    (match_dup 3)))]
11611   "reload_completed"
11612   [(set (match_dup 4)
11613         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11614                    (match_dup 3)))
11615    (set (match_dup 0)
11616         (compare:CC (match_dup 4)
11617                     (const_int 0)))]
11618   "")
11621 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11622                               (DI "rKJI")])
11624 (define_insn_and_split "eq<mode>3"
11625   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11626         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11627                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11628    (clobber (match_scratch:GPR 3 "=r"))
11629    (clobber (match_scratch:GPR 4 "=r"))]
11630   ""
11631   "#"
11632   ""
11633   [(set (match_dup 4)
11634         (clz:GPR (match_dup 3)))
11635    (set (match_dup 0)
11636         (lshiftrt:GPR (match_dup 4)
11637                       (match_dup 5)))]
11639   operands[3] = rs6000_emit_eqne (<MODE>mode,
11640                                   operands[1], operands[2], operands[3]);
11642   if (GET_CODE (operands[4]) == SCRATCH)
11643     operands[4] = gen_reg_rtx (<MODE>mode);
11645   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11647   [(set (attr "length")
11648         (if_then_else (match_test "operands[2] == const0_rtx")
11649                       (const_string "8")
11650                       (const_string "12")))])
11652 (define_insn_and_split "ne<mode>3"
11653   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11654         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11655               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11656    (clobber (match_scratch:P 3 "=r"))
11657    (clobber (match_scratch:P 4 "=r"))
11658    (clobber (reg:P CA_REGNO))]
11659   "!TARGET_ISEL"
11660   "#"
11661   ""
11662   [(parallel [(set (match_dup 4)
11663                    (plus:P (match_dup 3)
11664                            (const_int -1)))
11665               (set (reg:P CA_REGNO)
11666                    (ne:P (match_dup 3)
11667                          (const_int 0)))])
11668    (parallel [(set (match_dup 0)
11669                    (plus:P (plus:P (not:P (match_dup 4))
11670                                    (reg:P CA_REGNO))
11671                            (match_dup 3)))
11672               (clobber (reg:P CA_REGNO))])]
11674   operands[3] = rs6000_emit_eqne (<MODE>mode,
11675                                   operands[1], operands[2], operands[3]);
11677   if (GET_CODE (operands[4]) == SCRATCH)
11678     operands[4] = gen_reg_rtx (<MODE>mode);
11680   [(set (attr "length")
11681         (if_then_else (match_test "operands[2] == const0_rtx")
11682                       (const_string "8")
11683                       (const_string "12")))])
11685 (define_insn_and_split "*neg_eq_<mode>"
11686   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11687         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11688                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11689    (clobber (match_scratch:P 3 "=r"))
11690    (clobber (match_scratch:P 4 "=r"))
11691    (clobber (reg:P CA_REGNO))]
11692   ""
11693   "#"
11694   ""
11695   [(parallel [(set (match_dup 4)
11696                    (plus:P (match_dup 3)
11697                            (const_int -1)))
11698               (set (reg:P CA_REGNO)
11699                    (ne:P (match_dup 3)
11700                          (const_int 0)))])
11701    (parallel [(set (match_dup 0)
11702                    (plus:P (reg:P CA_REGNO)
11703                            (const_int -1)))
11704               (clobber (reg:P CA_REGNO))])]
11706   operands[3] = rs6000_emit_eqne (<MODE>mode,
11707                                   operands[1], operands[2], operands[3]);
11709   if (GET_CODE (operands[4]) == SCRATCH)
11710     operands[4] = gen_reg_rtx (<MODE>mode);
11712   [(set (attr "length")
11713         (if_then_else (match_test "operands[2] == const0_rtx")
11714                       (const_string "8")
11715                       (const_string "12")))])
11717 (define_insn_and_split "*neg_ne_<mode>"
11718   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11719         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11720                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11721    (clobber (match_scratch:P 3 "=r"))
11722    (clobber (match_scratch:P 4 "=r"))
11723    (clobber (reg:P CA_REGNO))]
11724   ""
11725   "#"
11726   ""
11727   [(parallel [(set (match_dup 4)
11728                    (neg:P (match_dup 3)))
11729               (set (reg:P CA_REGNO)
11730                    (eq:P (match_dup 3)
11731                          (const_int 0)))])
11732    (parallel [(set (match_dup 0)
11733                    (plus:P (reg:P CA_REGNO)
11734                            (const_int -1)))
11735               (clobber (reg:P CA_REGNO))])]
11737   operands[3] = rs6000_emit_eqne (<MODE>mode,
11738                                   operands[1], operands[2], operands[3]);
11740   if (GET_CODE (operands[4]) == SCRATCH)
11741     operands[4] = gen_reg_rtx (<MODE>mode);
11743   [(set (attr "length")
11744         (if_then_else (match_test "operands[2] == const0_rtx")
11745                       (const_string "8")
11746                       (const_string "12")))])
11748 (define_insn_and_split "*plus_eq_<mode>"
11749   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11750         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11751                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11752                 (match_operand:P 3 "gpc_reg_operand" "r")))
11753    (clobber (match_scratch:P 4 "=r"))
11754    (clobber (match_scratch:P 5 "=r"))
11755    (clobber (reg:P CA_REGNO))]
11756   ""
11757   "#"
11758   ""
11759   [(parallel [(set (match_dup 5)
11760                    (neg:P (match_dup 4)))
11761               (set (reg:P CA_REGNO)
11762                    (eq:P (match_dup 4)
11763                          (const_int 0)))])
11764    (parallel [(set (match_dup 0)
11765                    (plus:P (match_dup 3)
11766                            (reg:P CA_REGNO)))
11767               (clobber (reg:P CA_REGNO))])]
11769   operands[4] = rs6000_emit_eqne (<MODE>mode,
11770                                   operands[1], operands[2], operands[4]);
11772   if (GET_CODE (operands[5]) == SCRATCH)
11773     operands[5] = gen_reg_rtx (<MODE>mode);
11775   [(set (attr "length")
11776         (if_then_else (match_test "operands[2] == const0_rtx")
11777                       (const_string "8")
11778                       (const_string "12")))])
11780 (define_insn_and_split "*plus_ne_<mode>"
11781   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11782         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11783                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11784                 (match_operand:P 3 "gpc_reg_operand" "r")))
11785    (clobber (match_scratch:P 4 "=r"))
11786    (clobber (match_scratch:P 5 "=r"))
11787    (clobber (reg:P CA_REGNO))]
11788   ""
11789   "#"
11790   ""
11791   [(parallel [(set (match_dup 5)
11792                    (plus:P (match_dup 4)
11793                            (const_int -1)))
11794               (set (reg:P CA_REGNO)
11795                    (ne:P (match_dup 4)
11796                          (const_int 0)))])
11797    (parallel [(set (match_dup 0)
11798                    (plus:P (match_dup 3)
11799                            (reg:P CA_REGNO)))
11800               (clobber (reg:P CA_REGNO))])]
11802   operands[4] = rs6000_emit_eqne (<MODE>mode,
11803                                   operands[1], operands[2], operands[4]);
11805   if (GET_CODE (operands[5]) == SCRATCH)
11806     operands[5] = gen_reg_rtx (<MODE>mode);
11808   [(set (attr "length")
11809         (if_then_else (match_test "operands[2] == const0_rtx")
11810                       (const_string "8")
11811                       (const_string "12")))])
11813 (define_insn_and_split "*minus_eq_<mode>"
11814   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11815         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11816                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11817                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11818    (clobber (match_scratch:P 4 "=r"))
11819    (clobber (match_scratch:P 5 "=r"))
11820    (clobber (reg:P CA_REGNO))]
11821   ""
11822   "#"
11823   ""
11824   [(parallel [(set (match_dup 5)
11825                    (plus:P (match_dup 4)
11826                            (const_int -1)))
11827               (set (reg:P CA_REGNO)
11828                    (ne:P (match_dup 4)
11829                          (const_int 0)))])
11830    (parallel [(set (match_dup 0)
11831                    (plus:P (plus:P (match_dup 3)
11832                                    (reg:P CA_REGNO))
11833                            (const_int -1)))
11834               (clobber (reg:P CA_REGNO))])]
11836   operands[4] = rs6000_emit_eqne (<MODE>mode,
11837                                   operands[1], operands[2], operands[4]);
11839   if (GET_CODE (operands[5]) == SCRATCH)
11840     operands[5] = gen_reg_rtx (<MODE>mode);
11842   [(set (attr "length")
11843         (if_then_else (match_test "operands[2] == const0_rtx")
11844                       (const_string "8")
11845                       (const_string "12")))])
11847 (define_insn_and_split "*minus_ne_<mode>"
11848   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11849         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11850                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11851                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11852    (clobber (match_scratch:P 4 "=r"))
11853    (clobber (match_scratch:P 5 "=r"))
11854    (clobber (reg:P CA_REGNO))]
11855   ""
11856   "#"
11857   ""
11858   [(parallel [(set (match_dup 5)
11859                    (neg:P (match_dup 4)))
11860               (set (reg:P CA_REGNO)
11861                    (eq:P (match_dup 4)
11862                          (const_int 0)))])
11863    (parallel [(set (match_dup 0)
11864                    (plus:P (plus:P (match_dup 3)
11865                                    (reg:P CA_REGNO))
11866                            (const_int -1)))
11867               (clobber (reg:P CA_REGNO))])]
11869   operands[4] = rs6000_emit_eqne (<MODE>mode,
11870                                   operands[1], operands[2], operands[4]);
11872   if (GET_CODE (operands[5]) == SCRATCH)
11873     operands[5] = gen_reg_rtx (<MODE>mode);
11875   [(set (attr "length")
11876         (if_then_else (match_test "operands[2] == const0_rtx")
11877                       (const_string "8")
11878                       (const_string "12")))])
11880 (define_insn_and_split "*eqsi3_ext<mode>"
11881   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11882         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11883                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11884    (clobber (match_scratch:SI 3 "=r"))
11885    (clobber (match_scratch:SI 4 "=r"))]
11886   ""
11887   "#"
11888   ""
11889   [(set (match_dup 4)
11890         (clz:SI (match_dup 3)))
11891    (set (match_dup 0)
11892         (zero_extend:EXTSI
11893           (lshiftrt:SI (match_dup 4)
11894                        (const_int 5))))]
11896   operands[3] = rs6000_emit_eqne (SImode,
11897                                   operands[1], operands[2], operands[3]);
11899   if (GET_CODE (operands[4]) == SCRATCH)
11900     operands[4] = gen_reg_rtx (SImode);
11902   [(set (attr "length")
11903         (if_then_else (match_test "operands[2] == const0_rtx")
11904                       (const_string "8")
11905                       (const_string "12")))])
11907 (define_insn_and_split "*nesi3_ext<mode>"
11908   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11909         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11910                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11911    (clobber (match_scratch:SI 3 "=r"))
11912    (clobber (match_scratch:SI 4 "=r"))
11913    (clobber (match_scratch:EXTSI 5 "=r"))]
11914   ""
11915   "#"
11916   ""
11917   [(set (match_dup 4)
11918         (clz:SI (match_dup 3)))
11919    (set (match_dup 5)
11920         (zero_extend:EXTSI
11921           (lshiftrt:SI (match_dup 4)
11922                        (const_int 5))))
11923    (set (match_dup 0)
11924         (xor:EXTSI (match_dup 5)
11925                    (const_int 1)))]
11927   operands[3] = rs6000_emit_eqne (SImode,
11928                                   operands[1], operands[2], operands[3]);
11930   if (GET_CODE (operands[4]) == SCRATCH)
11931     operands[4] = gen_reg_rtx (SImode);
11932   if (GET_CODE (operands[5]) == SCRATCH)
11933     operands[5] = gen_reg_rtx (<MODE>mode);
11935   [(set (attr "length")
11936         (if_then_else (match_test "operands[2] == const0_rtx")
11937                       (const_string "12")
11938                       (const_string "16")))])
11940 ;; Define both directions of branch and return.  If we need a reload
11941 ;; register, we'd rather use CR0 since it is much easier to copy a
11942 ;; register CC value to there.
11944 (define_insn ""
11945   [(set (pc)
11946         (if_then_else (match_operator 1 "branch_comparison_operator"
11947                                       [(match_operand 2
11948                                                       "cc_reg_operand" "y")
11949                                        (const_int 0)])
11950                       (label_ref (match_operand 0 "" ""))
11951                       (pc)))]
11952   ""
11953   "*
11955   return output_cbranch (operands[1], \"%l0\", 0, insn);
11957   [(set_attr "type" "branch")])
11959 (define_insn ""
11960   [(set (pc)
11961         (if_then_else (match_operator 0 "branch_comparison_operator"
11962                                       [(match_operand 1
11963                                                       "cc_reg_operand" "y")
11964                                        (const_int 0)])
11965                       (any_return)
11966                       (pc)))]
11967   "<return_pred>"
11968   "*
11970   return output_cbranch (operands[0], NULL, 0, insn);
11972   [(set_attr "type" "jmpreg")
11973    (set_attr "length" "4")])
11975 (define_insn ""
11976   [(set (pc)
11977         (if_then_else (match_operator 1 "branch_comparison_operator"
11978                                       [(match_operand 2
11979                                                       "cc_reg_operand" "y")
11980                                        (const_int 0)])
11981                       (pc)
11982                       (label_ref (match_operand 0 "" ""))))]
11983   ""
11984   "*
11986   return output_cbranch (operands[1], \"%l0\", 1, insn);
11988   [(set_attr "type" "branch")])
11990 (define_insn ""
11991   [(set (pc)
11992         (if_then_else (match_operator 0 "branch_comparison_operator"
11993                                       [(match_operand 1
11994                                                       "cc_reg_operand" "y")
11995                                        (const_int 0)])
11996                       (pc)
11997                       (any_return)))]
11998   "<return_pred>"
11999   "*
12001   return output_cbranch (operands[0], NULL, 1, insn);
12003   [(set_attr "type" "jmpreg")
12004    (set_attr "length" "4")])
12006 ;; Logic on condition register values.
12008 ; This pattern matches things like
12009 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12010 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12011 ;                                  (const_int 1)))
12012 ; which are generated by the branch logic.
12013 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12015 (define_insn "*cceq_ior_compare"
12016   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12017         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12018                         [(match_operator:SI 2
12019                                       "branch_positive_comparison_operator"
12020                                       [(match_operand 3
12021                                                       "cc_reg_operand" "y,y")
12022                                        (const_int 0)])
12023                          (match_operator:SI 4
12024                                       "branch_positive_comparison_operator"
12025                                       [(match_operand 5
12026                                                       "cc_reg_operand" "0,y")
12027                                        (const_int 0)])])
12028                       (const_int 1)))]
12029   ""
12030   "cr%q1 %E0,%j2,%j4"
12031   [(set_attr "type" "cr_logical,delayed_cr")])
12033 ; Why is the constant -1 here, but 1 in the previous pattern?
12034 ; Because ~1 has all but the low bit set.
12035 (define_insn ""
12036   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12037         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12038                         [(not:SI (match_operator:SI 2
12039                                       "branch_positive_comparison_operator"
12040                                       [(match_operand 3
12041                                                       "cc_reg_operand" "y,y")
12042                                        (const_int 0)]))
12043                          (match_operator:SI 4
12044                                 "branch_positive_comparison_operator"
12045                                 [(match_operand 5
12046                                                 "cc_reg_operand" "0,y")
12047                                  (const_int 0)])])
12048                       (const_int -1)))]
12049   ""
12050   "cr%q1 %E0,%j2,%j4"
12051   [(set_attr "type" "cr_logical,delayed_cr")])
12053 (define_insn "*cceq_rev_compare"
12054   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12055         (compare:CCEQ (match_operator:SI 1
12056                                       "branch_positive_comparison_operator"
12057                                       [(match_operand 2
12058                                                       "cc_reg_operand" "0,y")
12059                                        (const_int 0)])
12060                       (const_int 0)))]
12061   ""
12062   "crnot %E0,%j1"
12063   [(set_attr "type" "cr_logical,delayed_cr")])
12065 ;; If we are comparing the result of two comparisons, this can be done
12066 ;; using creqv or crxor.
12068 (define_insn_and_split ""
12069   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12070         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12071                               [(match_operand 2 "cc_reg_operand" "y")
12072                                (const_int 0)])
12073                       (match_operator 3 "branch_comparison_operator"
12074                               [(match_operand 4 "cc_reg_operand" "y")
12075                                (const_int 0)])))]
12076   ""
12077   "#"
12078   ""
12079   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12080                                     (match_dup 5)))]
12081   "
12083   int positive_1, positive_2;
12085   positive_1 = branch_positive_comparison_operator (operands[1],
12086                                                     GET_MODE (operands[1]));
12087   positive_2 = branch_positive_comparison_operator (operands[3],
12088                                                     GET_MODE (operands[3]));
12090   if (! positive_1)
12091     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12092                                                             GET_CODE (operands[1])),
12093                                   SImode,
12094                                   operands[2], const0_rtx);
12095   else if (GET_MODE (operands[1]) != SImode)
12096     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12097                                   operands[2], const0_rtx);
12099   if (! positive_2)
12100     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12101                                                             GET_CODE (operands[3])),
12102                                   SImode,
12103                                   operands[4], const0_rtx);
12104   else if (GET_MODE (operands[3]) != SImode)
12105     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12106                                   operands[4], const0_rtx);
12108   if (positive_1 == positive_2)
12109     {
12110       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12111       operands[5] = constm1_rtx;
12112     }
12113   else
12114     {
12115       operands[5] = const1_rtx;
12116     }
12119 ;; Unconditional branch and return.
12121 (define_insn "jump"
12122   [(set (pc)
12123         (label_ref (match_operand 0 "" "")))]
12124   ""
12125   "b %l0"
12126   [(set_attr "type" "branch")])
12128 (define_insn "<return_str>return"
12129   [(any_return)]
12130   "<return_pred>"
12131   "blr"
12132   [(set_attr "type" "jmpreg")])
12134 (define_expand "indirect_jump"
12135   [(set (pc) (match_operand 0 "register_operand" ""))])
12137 (define_insn "*indirect_jump<mode>"
12138   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12139   ""
12140   "@
12141    bctr
12142    blr"
12143   [(set_attr "type" "jmpreg")])
12145 ;; Table jump for switch statements:
12146 (define_expand "tablejump"
12147   [(use (match_operand 0 "" ""))
12148    (use (label_ref (match_operand 1 "" "")))]
12149   ""
12150   "
12152   if (TARGET_32BIT)
12153     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12154   else
12155     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12156   DONE;
12159 (define_expand "tablejumpsi"
12160   [(set (match_dup 3)
12161         (plus:SI (match_operand:SI 0 "" "")
12162                  (match_dup 2)))
12163    (parallel [(set (pc) (match_dup 3))
12164               (use (label_ref (match_operand 1 "" "")))])]
12165   "TARGET_32BIT"
12166   "
12167 { operands[0] = force_reg (SImode, operands[0]);
12168   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12169   operands[3] = gen_reg_rtx (SImode);
12172 (define_expand "tablejumpdi"
12173   [(set (match_dup 4)
12174         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12175    (set (match_dup 3)
12176         (plus:DI (match_dup 4)
12177                  (match_dup 2)))
12178    (parallel [(set (pc) (match_dup 3))
12179               (use (label_ref (match_operand 1 "" "")))])]
12180   "TARGET_64BIT"
12181   "
12182 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12183   operands[3] = gen_reg_rtx (DImode);
12184   operands[4] = gen_reg_rtx (DImode);
12187 (define_insn "*tablejump<mode>_internal1"
12188   [(set (pc)
12189         (match_operand:P 0 "register_operand" "c,*l"))
12190    (use (label_ref (match_operand 1 "" "")))]
12191   ""
12192   "@
12193    bctr
12194    blr"
12195   [(set_attr "type" "jmpreg")])
12197 (define_insn "nop"
12198   [(unspec [(const_int 0)] UNSPEC_NOP)]
12199   ""
12200   "nop")
12202 (define_insn "group_ending_nop"
12203   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12204   ""
12205   "*
12207   if (rs6000_cpu_attr == CPU_POWER6)
12208     return \"ori 1,1,0\";
12209   return \"ori 2,2,0\";
12212 ;; Define the subtract-one-and-jump insns, starting with the template
12213 ;; so loop.c knows what to generate.
12215 (define_expand "doloop_end"
12216   [(use (match_operand 0 "" ""))        ; loop pseudo
12217    (use (match_operand 1 "" ""))]       ; label
12218   ""
12219   "
12221   if (TARGET_64BIT)
12222     {
12223       if (GET_MODE (operands[0]) != DImode)
12224         FAIL;
12225       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12226     }
12227   else
12228     {
12229       if (GET_MODE (operands[0]) != SImode)
12230         FAIL;
12231       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12232     }
12233   DONE;
12236 (define_expand "ctr<mode>"
12237   [(parallel [(set (pc)
12238                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12239                                      (const_int 1))
12240                                  (label_ref (match_operand 1 "" ""))
12241                                  (pc)))
12242               (set (match_dup 0)
12243                    (plus:P (match_dup 0)
12244                             (const_int -1)))
12245               (unspec [(const_int 0)] UNSPEC_DOLOOP)
12246               (clobber (match_scratch:CC 2 ""))
12247               (clobber (match_scratch:P 3 ""))])]
12248   ""
12249   "")
12251 ;; We need to be able to do this for any operand, including MEM, or we
12252 ;; will cause reload to blow up since we don't allow output reloads on
12253 ;; JUMP_INSNs.
12254 ;; For the length attribute to be calculated correctly, the
12255 ;; label MUST be operand 0.
12256 ;; The UNSPEC is present to prevent combine creating this pattern.
12258 (define_insn "*ctr<mode>_internal1"
12259   [(set (pc)
12260         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12261                           (const_int 1))
12262                       (label_ref (match_operand 0 "" ""))
12263                       (pc)))
12264    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12265         (plus:P (match_dup 1)
12266                  (const_int -1)))
12267    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12268    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12269    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12270   ""
12271   "*
12273   if (which_alternative != 0)
12274     return \"#\";
12275   else if (get_attr_length (insn) == 4)
12276     return \"bdnz %l0\";
12277   else
12278     return \"bdz $+8\;b %l0\";
12280   [(set_attr "type" "branch")
12281    (set_attr "length" "*,16,20,20")])
12283 (define_insn "*ctr<mode>_internal2"
12284   [(set (pc)
12285         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12286                           (const_int 1))
12287                       (pc)
12288                       (label_ref (match_operand 0 "" ""))))
12289    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12290         (plus:P (match_dup 1)
12291                  (const_int -1)))
12292    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12293    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12294    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12295   ""
12296   "*
12298   if (which_alternative != 0)
12299     return \"#\";
12300   else if (get_attr_length (insn) == 4)
12301     return \"bdz %l0\";
12302   else
12303     return \"bdnz $+8\;b %l0\";
12305   [(set_attr "type" "branch")
12306    (set_attr "length" "*,16,20,20")])
12308 ;; Similar but use EQ
12310 (define_insn "*ctr<mode>_internal5"
12311   [(set (pc)
12312         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12313                           (const_int 1))
12314                       (label_ref (match_operand 0 "" ""))
12315                       (pc)))
12316    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12317         (plus:P (match_dup 1)
12318                  (const_int -1)))
12319    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12320    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12321    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12322   ""
12323   "*
12325   if (which_alternative != 0)
12326     return \"#\";
12327   else if (get_attr_length (insn) == 4)
12328     return \"bdz %l0\";
12329   else
12330     return \"bdnz $+8\;b %l0\";
12332   [(set_attr "type" "branch")
12333    (set_attr "length" "*,16,20,20")])
12335 (define_insn "*ctr<mode>_internal6"
12336   [(set (pc)
12337         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12338                           (const_int 1))
12339                       (pc)
12340                       (label_ref (match_operand 0 "" ""))))
12341    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12342         (plus:P (match_dup 1)
12343                  (const_int -1)))
12344    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12345    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12346    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12347   ""
12348   "*
12350   if (which_alternative != 0)
12351     return \"#\";
12352   else if (get_attr_length (insn) == 4)
12353     return \"bdnz %l0\";
12354   else
12355     return \"bdz $+8\;b %l0\";
12357   [(set_attr "type" "branch")
12358    (set_attr "length" "*,16,20,20")])
12360 ;; Now the splitters if we could not allocate the CTR register
12362 (define_split
12363   [(set (pc)
12364         (if_then_else (match_operator 2 "comparison_operator"
12365                                       [(match_operand:P 1 "gpc_reg_operand" "")
12366                                        (const_int 1)])
12367                       (match_operand 5 "" "")
12368                       (match_operand 6 "" "")))
12369    (set (match_operand:P 0 "int_reg_operand" "")
12370         (plus:P (match_dup 1) (const_int -1)))
12371    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12372    (clobber (match_scratch:CC 3 ""))
12373    (clobber (match_scratch:P 4 ""))]
12374   "reload_completed"
12375   [(set (match_dup 3)
12376         (compare:CC (match_dup 1)
12377                     (const_int 1)))
12378    (set (match_dup 0)
12379         (plus:P (match_dup 1)
12380                 (const_int -1)))
12381    (set (pc) (if_then_else (match_dup 7)
12382                            (match_dup 5)
12383                            (match_dup 6)))]
12384   "
12385 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12386                                 operands[3], const0_rtx); }")
12388 (define_split
12389   [(set (pc)
12390         (if_then_else (match_operator 2 "comparison_operator"
12391                                       [(match_operand:P 1 "gpc_reg_operand" "")
12392                                        (const_int 1)])
12393                       (match_operand 5 "" "")
12394                       (match_operand 6 "" "")))
12395    (set (match_operand:P 0 "nonimmediate_operand" "")
12396         (plus:P (match_dup 1) (const_int -1)))
12397    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12398    (clobber (match_scratch:CC 3 ""))
12399    (clobber (match_scratch:P 4 ""))]
12400   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12401   [(set (match_dup 3)
12402         (compare:CC (match_dup 1)
12403                     (const_int 1)))
12404    (set (match_dup 4)
12405         (plus:P (match_dup 1)
12406                 (const_int -1)))
12407    (set (match_dup 0)
12408         (match_dup 4))
12409    (set (pc) (if_then_else (match_dup 7)
12410                            (match_dup 5)
12411                            (match_dup 6)))]
12412   "
12413 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12414                                 operands[3], const0_rtx); }")
12416 (define_insn "trap"
12417   [(trap_if (const_int 1) (const_int 0))]
12418   ""
12419   "trap"
12420   [(set_attr "type" "trap")])
12422 (define_expand "ctrap<mode>4"
12423   [(trap_if (match_operator 0 "ordered_comparison_operator"
12424                             [(match_operand:GPR 1 "register_operand")
12425                              (match_operand:GPR 2 "reg_or_short_operand")])
12426             (match_operand 3 "zero_constant" ""))]
12427   ""
12428   "")
12430 (define_insn ""
12431   [(trap_if (match_operator 0 "ordered_comparison_operator"
12432                             [(match_operand:GPR 1 "register_operand" "r")
12433                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12434             (const_int 0))]
12435   ""
12436   "t<wd>%V0%I2 %1,%2"
12437   [(set_attr "type" "trap")])
12439 ;; Insns related to generating the function prologue and epilogue.
12441 (define_expand "prologue"
12442   [(use (const_int 0))]
12443   ""
12445   rs6000_emit_prologue ();
12446   if (!TARGET_SCHED_PROLOG)
12447     emit_insn (gen_blockage ());
12448   DONE;
12451 (define_insn "*movesi_from_cr_one"
12452   [(match_parallel 0 "mfcr_operation"
12453                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12454                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12455                                      (match_operand 3 "immediate_operand" "n")]
12456                           UNSPEC_MOVESI_FROM_CR))])]
12457   "TARGET_MFCRF"
12458   "*
12460   int mask = 0;
12461   int i;
12462   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12463   {
12464     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12465     operands[4] = GEN_INT (mask);
12466     output_asm_insn (\"mfcr %1,%4\", operands);
12467   }
12468   return \"\";
12470   [(set_attr "type" "mfcrf")])
12472 (define_insn "movesi_from_cr"
12473   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12474         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12475                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12476                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12477                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12478                    UNSPEC_MOVESI_FROM_CR))]
12479   ""
12480   "mfcr %0"
12481   [(set_attr "type" "mfcr")])
12483 (define_insn "*crsave"
12484   [(match_parallel 0 "crsave_operation"
12485                    [(set (match_operand:SI 1 "memory_operand" "=m")
12486                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12487   ""
12488   "stw %2,%1"
12489   [(set_attr "type" "store")])
12491 (define_insn "*stmw"
12492   [(match_parallel 0 "stmw_operation"
12493                    [(set (match_operand:SI 1 "memory_operand" "=m")
12494                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12495   "TARGET_MULTIPLE"
12496   "stmw %2,%1"
12497   [(set_attr "type" "store")
12498    (set_attr "update" "yes")
12499    (set_attr "indexed" "yes")])
12501 ; The following comment applies to:
12502 ;     save_gpregs_*
12503 ;     save_fpregs_*
12504 ;     restore_gpregs*
12505 ;     return_and_restore_gpregs*
12506 ;     return_and_restore_fpregs*
12507 ;     return_and_restore_fpregs_aix*
12509 ; The out-of-line save / restore functions expects one input argument.
12510 ; Since those are not standard call_insn's, we must avoid using
12511 ; MATCH_OPERAND for that argument. That way the register rename
12512 ; optimization will not try to rename this register.
12513 ; Each pattern is repeated for each possible register number used in 
12514 ; various ABIs (r11, r1, and for some functions r12)
12516 (define_insn "*save_gpregs_<mode>_r11"
12517   [(match_parallel 0 "any_parallel_operand"
12518                    [(clobber (reg:P LR_REGNO))
12519                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12520                     (use (reg:P 11))
12521                     (set (match_operand:P 2 "memory_operand" "=m")
12522                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12523   ""
12524   "bl %1"
12525   [(set_attr "type" "branch")
12526    (set_attr "length" "4")])
12528 (define_insn "*save_gpregs_<mode>_r12"
12529   [(match_parallel 0 "any_parallel_operand"
12530                    [(clobber (reg:P LR_REGNO))
12531                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12532                     (use (reg:P 12))
12533                     (set (match_operand:P 2 "memory_operand" "=m")
12534                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12535   ""
12536   "bl %1"
12537   [(set_attr "type" "branch")
12538    (set_attr "length" "4")])
12540 (define_insn "*save_gpregs_<mode>_r1"
12541   [(match_parallel 0 "any_parallel_operand"
12542                    [(clobber (reg:P LR_REGNO))
12543                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12544                     (use (reg:P 1))
12545                     (set (match_operand:P 2 "memory_operand" "=m")
12546                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12547   ""
12548   "bl %1"
12549   [(set_attr "type" "branch")
12550    (set_attr "length" "4")])
12552 (define_insn "*save_fpregs_<mode>_r11"
12553   [(match_parallel 0 "any_parallel_operand"
12554                    [(clobber (reg:P LR_REGNO))
12555                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12556                     (use (reg:P 11))
12557                     (set (match_operand:DF 2 "memory_operand" "=m")
12558                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12559   ""
12560   "bl %1"
12561   [(set_attr "type" "branch")
12562    (set_attr "length" "4")])
12564 (define_insn "*save_fpregs_<mode>_r12"
12565   [(match_parallel 0 "any_parallel_operand"
12566                    [(clobber (reg:P LR_REGNO))
12567                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12568                     (use (reg:P 12))
12569                     (set (match_operand:DF 2 "memory_operand" "=m")
12570                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12571   ""
12572   "bl %1"
12573   [(set_attr "type" "branch")
12574    (set_attr "length" "4")])
12576 (define_insn "*save_fpregs_<mode>_r1"
12577   [(match_parallel 0 "any_parallel_operand"
12578                    [(clobber (reg:P LR_REGNO))
12579                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12580                     (use (reg:P 1))
12581                     (set (match_operand:DF 2 "memory_operand" "=m")
12582                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12583   ""
12584   "bl %1"
12585   [(set_attr "type" "branch")
12586    (set_attr "length" "4")])
12588 ; This is to explain that changes to the stack pointer should
12589 ; not be moved over loads from or stores to stack memory.
12590 (define_insn "stack_tie"
12591   [(match_parallel 0 "tie_operand"
12592                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12593   ""
12594   ""
12595   [(set_attr "length" "0")])
12597 (define_expand "epilogue"
12598   [(use (const_int 0))]
12599   ""
12601   if (!TARGET_SCHED_PROLOG)
12602     emit_insn (gen_blockage ());
12603   rs6000_emit_epilogue (FALSE);
12604   DONE;
12607 ; On some processors, doing the mtcrf one CC register at a time is
12608 ; faster (like on the 604e).  On others, doing them all at once is
12609 ; faster; for instance, on the 601 and 750.
12611 (define_expand "movsi_to_cr_one"
12612   [(set (match_operand:CC 0 "cc_reg_operand" "")
12613         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12614                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12615   ""
12616   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12618 (define_insn "*movsi_to_cr"
12619   [(match_parallel 0 "mtcrf_operation"
12620                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12621                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12622                                      (match_operand 3 "immediate_operand" "n")]
12623                                     UNSPEC_MOVESI_TO_CR))])]
12624  ""
12625  "*
12627   int mask = 0;
12628   int i;
12629   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12630     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12631   operands[4] = GEN_INT (mask);
12632   return \"mtcrf %4,%2\";
12634   [(set_attr "type" "mtcr")])
12636 (define_insn "*mtcrfsi"
12637   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12638         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12639                     (match_operand 2 "immediate_operand" "n")]
12640                    UNSPEC_MOVESI_TO_CR))]
12641   "GET_CODE (operands[0]) == REG
12642    && CR_REGNO_P (REGNO (operands[0]))
12643    && GET_CODE (operands[2]) == CONST_INT
12644    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12645   "mtcrf %R0,%1"
12646   [(set_attr "type" "mtcr")])
12648 ; The load-multiple instructions have similar properties.
12649 ; Note that "load_multiple" is a name known to the machine-independent
12650 ; code that actually corresponds to the PowerPC load-string.
12652 (define_insn "*lmw"
12653   [(match_parallel 0 "lmw_operation"
12654                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12655                          (match_operand:SI 2 "memory_operand" "m"))])]
12656   "TARGET_MULTIPLE"
12657   "lmw %1,%2"
12658   [(set_attr "type" "load")
12659    (set_attr "update" "yes")
12660    (set_attr "indexed" "yes")
12661    (set_attr "cell_micro" "always")])
12663 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12664 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12666 ; The following comment applies to:
12667 ;     save_gpregs_*
12668 ;     save_fpregs_*
12669 ;     restore_gpregs*
12670 ;     return_and_restore_gpregs*
12671 ;     return_and_restore_fpregs*
12672 ;     return_and_restore_fpregs_aix*
12674 ; The out-of-line save / restore functions expects one input argument.
12675 ; Since those are not standard call_insn's, we must avoid using
12676 ; MATCH_OPERAND for that argument. That way the register rename
12677 ; optimization will not try to rename this register.
12678 ; Each pattern is repeated for each possible register number used in 
12679 ; various ABIs (r11, r1, and for some functions r12)
12681 (define_insn "*restore_gpregs_<mode>_r11"
12682  [(match_parallel 0 "any_parallel_operand"
12683                   [(clobber (reg:P LR_REGNO))
12684                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12685                    (use (reg:P 11))
12686                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12687                         (match_operand:P 3 "memory_operand" "m"))])]
12688  ""
12689  "bl %1"
12690  [(set_attr "type" "branch")
12691   (set_attr "length" "4")])
12693 (define_insn "*restore_gpregs_<mode>_r12"
12694  [(match_parallel 0 "any_parallel_operand"
12695                   [(clobber (reg:P LR_REGNO))
12696                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12697                    (use (reg:P 12))
12698                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12699                         (match_operand:P 3 "memory_operand" "m"))])]
12700  ""
12701  "bl %1"
12702  [(set_attr "type" "branch")
12703   (set_attr "length" "4")])
12705 (define_insn "*restore_gpregs_<mode>_r1"
12706  [(match_parallel 0 "any_parallel_operand"
12707                   [(clobber (reg:P LR_REGNO))
12708                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12709                    (use (reg:P 1))
12710                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12711                         (match_operand:P 3 "memory_operand" "m"))])]
12712  ""
12713  "bl %1"
12714  [(set_attr "type" "branch")
12715   (set_attr "length" "4")])
12717 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12718  [(match_parallel 0 "any_parallel_operand"
12719                   [(return)
12720                    (clobber (reg:P LR_REGNO))
12721                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12722                    (use (reg:P 11))
12723                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12724                         (match_operand:P 3 "memory_operand" "m"))])]
12725  ""
12726  "b %1"
12727  [(set_attr "type" "branch")
12728   (set_attr "length" "4")])
12730 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12731  [(match_parallel 0 "any_parallel_operand"
12732                   [(return)
12733                    (clobber (reg:P LR_REGNO))
12734                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12735                    (use (reg:P 12))
12736                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12737                         (match_operand:P 3 "memory_operand" "m"))])]
12738  ""
12739  "b %1"
12740  [(set_attr "type" "branch")
12741   (set_attr "length" "4")])
12743 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12744  [(match_parallel 0 "any_parallel_operand"
12745                   [(return)
12746                    (clobber (reg:P LR_REGNO))
12747                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12748                    (use (reg:P 1))
12749                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12750                         (match_operand:P 3 "memory_operand" "m"))])]
12751  ""
12752  "b %1"
12753  [(set_attr "type" "branch")
12754   (set_attr "length" "4")])
12756 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12757  [(match_parallel 0 "any_parallel_operand"
12758                   [(return)
12759                    (clobber (reg:P LR_REGNO))
12760                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12761                    (use (reg:P 11))
12762                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12763                         (match_operand:DF 3 "memory_operand" "m"))])]
12764  ""
12765  "b %1"
12766  [(set_attr "type" "branch")
12767   (set_attr "length" "4")])
12769 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12770  [(match_parallel 0 "any_parallel_operand"
12771                   [(return)
12772                    (clobber (reg:P LR_REGNO))
12773                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12774                    (use (reg:P 12))
12775                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12776                         (match_operand:DF 3 "memory_operand" "m"))])]
12777  ""
12778  "b %1"
12779  [(set_attr "type" "branch")
12780   (set_attr "length" "4")])
12782 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12783  [(match_parallel 0 "any_parallel_operand"
12784                   [(return)
12785                    (clobber (reg:P LR_REGNO))
12786                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12787                    (use (reg:P 1))
12788                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12789                         (match_operand:DF 3 "memory_operand" "m"))])]
12790  ""
12791  "b %1"
12792  [(set_attr "type" "branch")
12793   (set_attr "length" "4")])
12795 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12796  [(match_parallel 0 "any_parallel_operand"
12797                   [(return)
12798                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12799                    (use (reg:P 11))
12800                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12801                         (match_operand:DF 3 "memory_operand" "m"))])]
12802  ""
12803  "b %1"
12804  [(set_attr "type" "branch")
12805   (set_attr "length" "4")])
12807 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12808  [(match_parallel 0 "any_parallel_operand"
12809                   [(return)
12810                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12811                    (use (reg:P 1))
12812                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12813                         (match_operand:DF 3 "memory_operand" "m"))])]
12814  ""
12815  "b %1"
12816  [(set_attr "type" "branch")
12817   (set_attr "length" "4")])
12819 ; This is used in compiling the unwind routines.
12820 (define_expand "eh_return"
12821   [(use (match_operand 0 "general_operand" ""))]
12822   ""
12823   "
12825   if (TARGET_32BIT)
12826     emit_insn (gen_eh_set_lr_si (operands[0]));
12827   else
12828     emit_insn (gen_eh_set_lr_di (operands[0]));
12829   DONE;
12832 ; We can't expand this before we know where the link register is stored.
12833 (define_insn "eh_set_lr_<mode>"
12834   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12835                     UNSPECV_EH_RR)
12836    (clobber (match_scratch:P 1 "=&b"))]
12837   ""
12838   "#")
12840 (define_split
12841   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12842    (clobber (match_scratch 1 ""))]
12843   "reload_completed"
12844   [(const_int 0)]
12845   "
12847   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12848   DONE;
12851 (define_insn "prefetch"
12852   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12853              (match_operand:SI 1 "const_int_operand" "n")
12854              (match_operand:SI 2 "const_int_operand" "n"))]
12855   ""
12856   "*
12858   if (GET_CODE (operands[0]) == REG)
12859     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12860   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12862   [(set_attr "type" "load")])
12864 ;; Handle -fsplit-stack.
12866 (define_expand "split_stack_prologue"
12867   [(const_int 0)]
12868   ""
12870   rs6000_expand_split_stack_prologue ();
12871   DONE;
12874 (define_expand "load_split_stack_limit"
12875   [(set (match_operand 0)
12876         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12877   ""
12879   emit_insn (gen_rtx_SET (operands[0],
12880                           gen_rtx_UNSPEC (Pmode,
12881                                           gen_rtvec (1, const0_rtx),
12882                                           UNSPEC_STACK_CHECK)));
12883   DONE;
12886 (define_insn "load_split_stack_limit_di"
12887   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12888         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12889   "TARGET_64BIT"
12890   "ld %0,-0x7040(13)"
12891   [(set_attr "type" "load")
12892    (set_attr "update" "no")
12893    (set_attr "indexed" "no")])
12895 (define_insn "load_split_stack_limit_si"
12896   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12897         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12898   "!TARGET_64BIT"
12899   "lwz %0,-0x7020(2)"
12900   [(set_attr "type" "load")
12901    (set_attr "update" "no")
12902    (set_attr "indexed" "no")])
12904 ;; A return instruction which the middle-end doesn't see.
12905 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12906 ;; after the call to __morestack.
12907 (define_insn "split_stack_return"
12908   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12909   ""
12910   "blr"
12911   [(set_attr "type" "jmpreg")])
12913 ;; If there are operand 0 bytes available on the stack, jump to
12914 ;; operand 1.
12915 (define_expand "split_stack_space_check"
12916   [(set (match_dup 2)
12917         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12918    (set (match_dup 3)
12919         (minus (reg STACK_POINTER_REGNUM)
12920                (match_operand 0)))
12921    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12922    (set (pc) (if_then_else
12923               (geu (match_dup 4) (const_int 0))
12924               (label_ref (match_operand 1))
12925               (pc)))]
12926   ""
12928   rs6000_split_stack_space_check (operands[0], operands[1]);
12929   DONE;
12932 (define_insn "bpermd_<mode>"
12933   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12934         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12935                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12936   "TARGET_POPCNTD"
12937   "bpermd %0,%1,%2"
12938   [(set_attr "type" "popcnt")])
12941 ;; Builtin fma support.  Handle 
12942 ;; Note that the conditions for expansion are in the FMA_F iterator.
12944 (define_expand "fma<mode>4"
12945   [(set (match_operand:FMA_F 0 "register_operand" "")
12946         (fma:FMA_F
12947           (match_operand:FMA_F 1 "register_operand" "")
12948           (match_operand:FMA_F 2 "register_operand" "")
12949           (match_operand:FMA_F 3 "register_operand" "")))]
12950   ""
12951   "")
12953 (define_insn "*fma<mode>4_fpr"
12954   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12955         (fma:SFDF
12956           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12957           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12958           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12959   "TARGET_<MODE>_FPR"
12960   "@
12961    fmadd<Ftrad> %0,%1,%2,%3
12962    xsmadda<Fvsx> %x0,%x1,%x2
12963    xsmaddm<Fvsx> %x0,%x1,%x3"
12964   [(set_attr "type" "fp")
12965    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12967 ; Altivec only has fma and nfms.
12968 (define_expand "fms<mode>4"
12969   [(set (match_operand:FMA_F 0 "register_operand" "")
12970         (fma:FMA_F
12971           (match_operand:FMA_F 1 "register_operand" "")
12972           (match_operand:FMA_F 2 "register_operand" "")
12973           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12974   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12975   "")
12977 (define_insn "*fms<mode>4_fpr"
12978   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12979         (fma:SFDF
12980          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12981          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12982          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12983   "TARGET_<MODE>_FPR"
12984   "@
12985    fmsub<Ftrad> %0,%1,%2,%3
12986    xsmsuba<Fvsx> %x0,%x1,%x2
12987    xsmsubm<Fvsx> %x0,%x1,%x3"
12988   [(set_attr "type" "fp")
12989    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12991 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12992 (define_expand "fnma<mode>4"
12993   [(set (match_operand:FMA_F 0 "register_operand" "")
12994         (neg:FMA_F
12995           (fma:FMA_F
12996             (match_operand:FMA_F 1 "register_operand" "")
12997             (match_operand:FMA_F 2 "register_operand" "")
12998             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12999   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13000   "")
13002 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13003 (define_expand "fnms<mode>4"
13004   [(set (match_operand:FMA_F 0 "register_operand" "")
13005         (neg:FMA_F
13006           (fma:FMA_F
13007             (match_operand:FMA_F 1 "register_operand" "")
13008             (match_operand:FMA_F 2 "register_operand" "")
13009             (match_operand:FMA_F 3 "register_operand" ""))))]
13010   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13011   "")
13013 ; Not an official optab name, but used from builtins.
13014 (define_expand "nfma<mode>4"
13015   [(set (match_operand:FMA_F 0 "register_operand" "")
13016         (neg:FMA_F
13017           (fma:FMA_F
13018             (match_operand:FMA_F 1 "register_operand" "")
13019             (match_operand:FMA_F 2 "register_operand" "")
13020             (match_operand:FMA_F 3 "register_operand" ""))))]
13021   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13022   "")
13024 (define_insn "*nfma<mode>4_fpr"
13025   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13026         (neg:SFDF
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    fnmadd<Ftrad> %0,%1,%2,%3
13034    xsnmadda<Fvsx> %x0,%x1,%x2
13035    xsnmaddm<Fvsx> %x0,%x1,%x3"
13036   [(set_attr "type" "fp")
13037    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13039 ; Not an official optab name, but used from builtins.
13040 (define_expand "nfms<mode>4"
13041   [(set (match_operand:FMA_F 0 "register_operand" "")
13042         (neg:FMA_F
13043           (fma:FMA_F
13044             (match_operand:FMA_F 1 "register_operand" "")
13045             (match_operand:FMA_F 2 "register_operand" "")
13046             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13047   ""
13048   "")
13050 (define_insn "*nfmssf4_fpr"
13051   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13052         (neg:SFDF
13053          (fma:SFDF
13054           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13055           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13056           (neg:SFDF
13057            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13058   "TARGET_<MODE>_FPR"
13059   "@
13060    fnmsub<Ftrad> %0,%1,%2,%3
13061    xsnmsuba<Fvsx> %x0,%x1,%x2
13062    xsnmsubm<Fvsx> %x0,%x1,%x3"
13063   [(set_attr "type" "fp")
13064    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13067 (define_expand "rs6000_get_timebase"
13068   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13069   ""
13071   if (TARGET_POWERPC64)
13072     emit_insn (gen_rs6000_mftb_di (operands[0]));
13073   else
13074     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13075   DONE;
13078 (define_insn "rs6000_get_timebase_ppc32"
13079   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13080         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13081    (clobber (match_scratch:SI 1 "=r"))
13082    (clobber (match_scratch:CC 2 "=y"))]
13083   "!TARGET_POWERPC64"
13085   if (WORDS_BIG_ENDIAN)
13086     if (TARGET_MFCRF)
13087       {
13088         return "mfspr %0,269\;"
13089                "mfspr %L0,268\;"
13090                "mfspr %1,269\;"
13091                "cmpw %2,%0,%1\;"
13092                "bne- %2,$-16";
13093       }
13094     else
13095       {
13096         return "mftbu %0\;"
13097                "mftb %L0\;"
13098                "mftbu %1\;"
13099                "cmpw %2,%0,%1\;"
13100                "bne- %2,$-16";
13101       }
13102   else
13103     if (TARGET_MFCRF)
13104       {
13105         return "mfspr %L0,269\;"
13106                "mfspr %0,268\;"
13107                "mfspr %1,269\;"
13108                "cmpw %2,%L0,%1\;"
13109                "bne- %2,$-16";
13110       }
13111     else
13112       {
13113         return "mftbu %L0\;"
13114                "mftb %0\;"
13115                "mftbu %1\;"
13116                "cmpw %2,%L0,%1\;"
13117                "bne- %2,$-16";
13118       }
13120   [(set_attr "length" "20")])
13122 (define_insn "rs6000_mftb_<mode>"
13123   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13124         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13125   ""
13127   if (TARGET_MFCRF)
13128     return "mfspr %0,268";
13129   else
13130     return "mftb %0";
13134 (define_insn "rs6000_mffs"
13135   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13136         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13137   "TARGET_HARD_FLOAT && TARGET_FPRS"
13138   "mffs %0")
13140 (define_insn "rs6000_mtfsf"
13141   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13142                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13143                     UNSPECV_MTFSF)]
13144   "TARGET_HARD_FLOAT && TARGET_FPRS"
13145   "mtfsf %0,%1")
13148 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13149 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13150 ;; register that is being loaded.  The fused ops must be physically adjacent.
13152 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13153 ;; before register allocation, and is meant to reduce the lifetime for the
13154 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13155 ;; to use the register that is being load.  The peephole2 then gathers any
13156 ;; other fused possibilities that it can find after register allocation.  If
13157 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13159 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13160 ;; before register allocation, so that we can avoid allocating a temporary base
13161 ;; register that won't be used, and that we try to load into base registers,
13162 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13163 ;; (addis followed by load) even on power8.
13165 (define_split
13166   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13167         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13168   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13169   [(parallel [(set (match_dup 0) (match_dup 2))
13170               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13171               (use (match_dup 3))
13172               (clobber (scratch:DI))])]
13174   operands[2] = fusion_wrap_memory_address (operands[1]);
13175   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13178 (define_insn "*toc_fusionload_<mode>"
13179   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13180         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13181    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13182    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13183    (clobber (match_scratch:DI 3 "=X,&b"))]
13184   "TARGET_TOC_FUSION_INT"
13186   if (base_reg_operand (operands[0], <MODE>mode))
13187     return emit_fusion_gpr_load (operands[0], operands[1]);
13189   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13191   [(set_attr "type" "load")
13192    (set_attr "length" "8")])
13194 (define_insn "*toc_fusionload_di"
13195   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13196         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13197    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13198    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13199    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13200   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13201    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13203   if (base_reg_operand (operands[0], DImode))
13204     return emit_fusion_gpr_load (operands[0], operands[1]);
13206   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13208   [(set_attr "type" "load")
13209    (set_attr "length" "8")])
13212 ;; Find cases where the addis that feeds into a load instruction is either used
13213 ;; once or is the same as the target register, and replace it with the fusion
13214 ;; insn
13216 (define_peephole2
13217   [(set (match_operand:P 0 "base_reg_operand" "")
13218         (match_operand:P 1 "fusion_gpr_addis" ""))
13219    (set (match_operand:INT1 2 "base_reg_operand" "")
13220         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13221   "TARGET_P8_FUSION
13222    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13223                          operands[3])"
13224   [(const_int 0)]
13226   expand_fusion_gpr_load (operands);
13227   DONE;
13230 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13231 ;; reload)
13233 (define_insn "fusion_gpr_load_<mode>"
13234   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13235         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13236                      UNSPEC_FUSION_GPR))]
13237   "TARGET_P8_FUSION"
13239   return emit_fusion_gpr_load (operands[0], operands[1]);
13241   [(set_attr "type" "load")
13242    (set_attr "length" "8")])
13245 ;; ISA 3.0 (power9) fusion support
13246 ;; Merge addis with floating load/store to FPRs (or GPRs).
13247 (define_peephole2
13248   [(set (match_operand:P 0 "base_reg_operand" "")
13249         (match_operand:P 1 "fusion_gpr_addis" ""))
13250    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13251         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13252   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13253    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13254   [(const_int 0)]
13256   expand_fusion_p9_load (operands);
13257   DONE;
13260 (define_peephole2
13261   [(set (match_operand:P 0 "base_reg_operand" "")
13262         (match_operand:P 1 "fusion_gpr_addis" ""))
13263    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13264         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13265   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13266    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13267   [(const_int 0)]
13269   expand_fusion_p9_store (operands);
13270   DONE;
13273 (define_peephole2
13274   [(set (match_operand:SDI 0 "int_reg_operand" "")
13275         (match_operand:SDI 1 "upper16_cint_operand" ""))
13276    (set (match_dup 0)
13277         (ior:SDI (match_dup 0)
13278                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13279   "TARGET_P9_FUSION"
13280   [(set (match_dup 0)
13281         (unspec:SDI [(match_dup 1)
13282                      (match_dup 2)] UNSPEC_FUSION_P9))])
13284 (define_peephole2
13285   [(set (match_operand:SDI 0 "int_reg_operand" "")
13286         (match_operand:SDI 1 "upper16_cint_operand" ""))
13287    (set (match_operand:SDI 2 "int_reg_operand" "")
13288         (ior:SDI (match_dup 0)
13289                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13290   "TARGET_P9_FUSION
13291    && !rtx_equal_p (operands[0], operands[2])
13292    && peep2_reg_dead_p (2, operands[0])"
13293   [(set (match_dup 2)
13294         (unspec:SDI [(match_dup 1)
13295                      (match_dup 3)] UNSPEC_FUSION_P9))])
13297 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13298 ;; reload).  Because we want to eventually have secondary_reload generate
13299 ;; these, they have to have a single alternative that gives the register
13300 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13301 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13302   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13303         (unspec:GPR_FUSION
13304          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13305          UNSPEC_FUSION_P9))
13306    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13307   "TARGET_P9_FUSION"
13309   /* This insn is a secondary reload insn, which cannot have alternatives.
13310      If we are not loading up register 0, use the power8 fusion instead.  */
13311   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13312     return emit_fusion_gpr_load (operands[0], operands[1]);
13314   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13316   [(set_attr "type" "load")
13317    (set_attr "length" "8")])
13319 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13320   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13321         (unspec:GPR_FUSION
13322          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13323          UNSPEC_FUSION_P9))
13324    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13325   "TARGET_P9_FUSION"
13327   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13329   [(set_attr "type" "store")
13330    (set_attr "length" "8")])
13332 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13333   [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13334         (unspec:FPR_FUSION
13335          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13336          UNSPEC_FUSION_P9))
13337    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13338   "TARGET_P9_FUSION"
13340   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13342   [(set_attr "type" "fpload")
13343    (set_attr "length" "8")])
13345 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13346   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13347         (unspec:FPR_FUSION
13348          [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13349          UNSPEC_FUSION_P9))
13350    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13351   "TARGET_P9_FUSION"
13353   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13355   [(set_attr "type" "fpstore")
13356    (set_attr "length" "8")])
13358 (define_insn "*fusion_p9_<mode>_constant"
13359   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13360         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13361                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13362                     UNSPEC_FUSION_P9))] 
13363   "TARGET_P9_FUSION"
13365   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13366   return "ori %0,%0,%2";
13368   [(set_attr "type" "two")
13369    (set_attr "length" "8")])
13372 ;; Miscellaneous ISA 2.06 (power7) instructions
13373 (define_insn "addg6s"
13374   [(set (match_operand:SI 0 "register_operand" "=r")
13375         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13376                     (match_operand:SI 2 "register_operand" "r")]
13377                    UNSPEC_ADDG6S))]
13378   "TARGET_POPCNTD"
13379   "addg6s %0,%1,%2"
13380   [(set_attr "type" "integer")
13381    (set_attr "length" "4")])
13383 (define_insn "cdtbcd"
13384   [(set (match_operand:SI 0 "register_operand" "=r")
13385         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13386                    UNSPEC_CDTBCD))]
13387   "TARGET_POPCNTD"
13388   "cdtbcd %0,%1"
13389   [(set_attr "type" "integer")
13390    (set_attr "length" "4")])
13392 (define_insn "cbcdtd"
13393   [(set (match_operand:SI 0 "register_operand" "=r")
13394         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13395                    UNSPEC_CBCDTD))]
13396   "TARGET_POPCNTD"
13397   "cbcdtd %0,%1"
13398   [(set_attr "type" "integer")
13399    (set_attr "length" "4")])
13401 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13402                                         UNSPEC_DIVEO
13403                                         UNSPEC_DIVEU
13404                                         UNSPEC_DIVEUO])
13406 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13407                              (UNSPEC_DIVEO      "eo")
13408                              (UNSPEC_DIVEU      "eu")
13409                              (UNSPEC_DIVEUO     "euo")])
13411 (define_insn "div<div_extend>_<mode>"
13412   [(set (match_operand:GPR 0 "register_operand" "=r")
13413         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13414                      (match_operand:GPR 2 "register_operand" "r")]
13415                     UNSPEC_DIV_EXTEND))]
13416   "TARGET_POPCNTD"
13417   "div<wd><div_extend> %0,%1,%2"
13418   [(set_attr "type" "div")
13419    (set_attr "size" "<bits>")])
13422 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13424 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13425 (define_mode_attr FP128_64 [(TF "DF")
13426                             (IF "DF")
13427                             (TD "DI")
13428                             (KF "DI")])
13430 (define_expand "unpack<mode>"
13431   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13432         (unspec:<FP128_64>
13433          [(match_operand:FMOVE128 1 "register_operand" "")
13434           (match_operand:QI 2 "const_0_to_1_operand" "")]
13435          UNSPEC_UNPACK_128BIT))]
13436   "FLOAT128_2REG_P (<MODE>mode)"
13437   "")
13439 (define_insn_and_split "unpack<mode>_dm"
13440   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13441         (unspec:<FP128_64>
13442          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13443           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13444          UNSPEC_UNPACK_128BIT))]
13445   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13446   "#"
13447   "&& reload_completed"
13448   [(set (match_dup 0) (match_dup 3))]
13450   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13452   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13453     {
13454       emit_note (NOTE_INSN_DELETED);
13455       DONE;
13456     }
13458   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13460   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13461    (set_attr "length" "4")])
13463 (define_insn_and_split "unpack<mode>_nodm"
13464   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13465         (unspec:<FP128_64>
13466          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13467           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13468          UNSPEC_UNPACK_128BIT))]
13469   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13470   "#"
13471   "&& reload_completed"
13472   [(set (match_dup 0) (match_dup 3))]
13474   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13476   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13477     {
13478       emit_note (NOTE_INSN_DELETED);
13479       DONE;
13480     }
13482   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13484   [(set_attr "type" "fp,fpstore")
13485    (set_attr "length" "4")])
13487 (define_insn_and_split "pack<mode>"
13488   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13489         (unspec:FMOVE128
13490          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13491           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13492          UNSPEC_PACK_128BIT))]
13493   "FLOAT128_2REG_P (<MODE>mode)"
13494   "@
13495    fmr %L0,%2
13496    #"
13497   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13498   [(set (match_dup 3) (match_dup 1))
13499    (set (match_dup 4) (match_dup 2))]
13501   unsigned dest_hi = REGNO (operands[0]);
13502   unsigned dest_lo = dest_hi + 1;
13504   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13505   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13507   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13508   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13510   [(set_attr "type" "fpsimple,fp")
13511    (set_attr "length" "4,8")])
13513 (define_insn "unpack<mode>"
13514   [(set (match_operand:DI 0 "register_operand" "=d,d")
13515         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13516                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13517          UNSPEC_UNPACK_128BIT))]
13518   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13520   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13521     return ASM_COMMENT_START " xxpermdi to same register";
13523   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13524   return "xxpermdi %x0,%x1,%x1,%3";
13526   [(set_attr "type" "vecperm")])
13528 (define_insn "pack<mode>"
13529   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13530         (unspec:FMOVE128_VSX
13531          [(match_operand:DI 1 "register_operand" "d")
13532           (match_operand:DI 2 "register_operand" "d")]
13533          UNSPEC_PACK_128BIT))]
13534   "TARGET_VSX"
13535   "xxpermdi %x0,%x1,%x2,0"
13536   [(set_attr "type" "vecperm")])
13540 ;; ISA 2.08 IEEE 128-bit floating point support.
13542 (define_insn "add<mode>3"
13543   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13544         (plus:IEEE128
13545          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13546          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13547   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13548   "xsaddqp %0,%1,%2"
13549   [(set_attr "type" "vecfloat")
13550    (set_attr "size" "128")])
13552 (define_insn "sub<mode>3"
13553   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13554         (minus:IEEE128
13555          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13556          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13557   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13558   "xssubqp %0,%1,%2"
13559   [(set_attr "type" "vecfloat")
13560    (set_attr "size" "128")])
13562 (define_insn "mul<mode>3"
13563   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13564         (mult:IEEE128
13565          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13566          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13567   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13568   "xsmulqp %0,%1,%2"
13569   [(set_attr "type" "vecfloat")
13570    (set_attr "size" "128")])
13572 (define_insn "div<mode>3"
13573   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13574         (div:IEEE128
13575          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13576          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13577   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13578   "xsdivqp %0,%1,%2"
13579   [(set_attr "type" "vecdiv")
13580    (set_attr "size" "128")])
13582 (define_insn "sqrt<mode>2"
13583   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13584         (sqrt:IEEE128
13585          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13586   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13587    "xssqrtqp %0,%1"
13588   [(set_attr "type" "vecdiv")
13589    (set_attr "size" "128")])
13591 (define_expand "copysign<mode>3"
13592   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13593    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13594    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13595   "FLOAT128_IEEE_P (<MODE>mode)"
13597   if (TARGET_FLOAT128_HW)
13598     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13599                                          operands[2]));
13600   else
13601     {
13602       rtx tmp = gen_reg_rtx (<MODE>mode);
13603       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13604                                            operands[2], tmp));
13605     }
13606   DONE;
13609 (define_insn "copysign<mode>3_hard"
13610   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13611         (unspec:IEEE128
13612          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13613           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13614          UNSPEC_COPYSIGN))]
13615   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13616    "xscpsgnqp %0,%2,%1"
13617   [(set_attr "type" "vecmove")
13618    (set_attr "size" "128")])
13620 (define_insn "copysign<mode>3_soft"
13621   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13622         (unspec:IEEE128
13623          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13624           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13625           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13626          UNSPEC_COPYSIGN))]
13627   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13628    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13629   [(set_attr "type" "veccomplex")
13630    (set_attr "length" "8")])
13632 (define_insn "neg<mode>2_hw"
13633   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13634         (neg:IEEE128
13635          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13636   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13637   "xsnegqp %0,%1"
13638   [(set_attr "type" "vecmove")
13639    (set_attr "size" "128")])
13642 (define_insn "abs<mode>2_hw"
13643   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13644         (abs:IEEE128
13645          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13646   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13647   "xsabsqp %0,%1"
13648   [(set_attr "type" "vecmove")
13649    (set_attr "size" "128")])
13652 (define_insn "*nabs<mode>2_hw"
13653   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13654         (neg:IEEE128
13655          (abs:IEEE128
13656           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13657   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13658   "xsnabsqp %0,%1"
13659   [(set_attr "type" "vecmove")
13660    (set_attr "size" "128")])
13662 ;; Initially don't worry about doing fusion
13663 (define_insn "*fma<mode>4_hw"
13664   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13665         (fma:IEEE128
13666          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13667          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13668          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13669   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13670   "xsmaddqp %0,%1,%2"
13671   [(set_attr "type" "vecfloat")
13672    (set_attr "size" "128")])
13674 (define_insn "*fms<mode>4_hw"
13675   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13676         (fma:IEEE128
13677          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13678          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13679          (neg:IEEE128
13680           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13681   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13682   "xsmsubqp %0,%1,%2"
13683   [(set_attr "type" "vecfloat")
13684    (set_attr "size" "128")])
13686 (define_insn "*nfma<mode>4_hw"
13687   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13688         (neg:IEEE128
13689          (fma:IEEE128
13690           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13691           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13692           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13693   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13694   "xsnmaddqp %0,%1,%2"
13695   [(set_attr "type" "vecfloat")
13696    (set_attr "size" "128")])
13698 (define_insn "*nfms<mode>4_hw"
13699   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13700         (neg:IEEE128
13701          (fma:IEEE128
13702           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13703           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13704           (neg:IEEE128
13705            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13706   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13707   "xsnmsubqp %0,%1,%2"
13708   [(set_attr "type" "vecfloat")
13709    (set_attr "size" "128")])
13711 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13712   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13713         (float_extend:IEEE128
13714          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13715   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13716   "xscvdpqp %0,%1"
13717   [(set_attr "type" "vecfloat")
13718    (set_attr "size" "128")])
13720 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13721 ;; point is a simple copy.
13722 (define_insn_and_split "extendkftf2"
13723   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13724         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13725   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13726   "@
13727    #
13728    xxlor %x0,%x1,%x1"
13729   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13730   [(const_int 0)]
13732   emit_note (NOTE_INSN_DELETED);
13733   DONE;
13735   [(set_attr "type" "*,veclogical")
13736    (set_attr "length" "0,4")])
13738 (define_insn_and_split "trunctfkf2"
13739   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13740         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13741   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13742   "@
13743    #
13744    xxlor %x0,%x1,%x1"
13745   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13746   [(const_int 0)]
13748   emit_note (NOTE_INSN_DELETED);
13749   DONE;
13751   [(set_attr "type" "*,veclogical")
13752    (set_attr "length" "0,4")])
13754 (define_insn "trunc<mode>df2_hw"
13755   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13756         (float_truncate:DF
13757          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13758   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13759   "xscvqpdp %0,%1"
13760   [(set_attr "type" "vecfloat")
13761    (set_attr "size" "128")])
13763 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13764 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13765 ;; conversion
13766 (define_insn_and_split "trunc<mode>sf2_hw"
13767   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13768         (float_truncate:SF
13769          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13770    (clobber (match_scratch:DF 2 "=v"))]
13771   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13772   "#"
13773   "&& 1"
13774   [(set (match_dup 2)
13775         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13776    (set (match_dup 0)
13777         (float_truncate:SF (match_dup 2)))]
13779   if (GET_CODE (operands[2]) == SCRATCH)
13780     operands[2] = gen_reg_rtx (DFmode);
13782   [(set_attr "type" "vecfloat")
13783    (set_attr "length" "8")])
13785 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13786 ;; allowed in the traditional floating point registers. Use V2DImode so that
13787 ;; we can get a value in an Altivec register.
13789 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13790   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13791         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13792    (clobber (match_scratch:V2DI 2 "=v,v"))]
13793   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13794   "#"
13795   "&& 1"
13796   [(pc)]
13798   convert_float128_to_int (operands, <CODE>);
13799   DONE;
13801   [(set_attr "length" "8")
13802    (set_attr "type" "mftgpr,fpstore")])
13804 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13805   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13806         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13807    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13808   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13809   "#"
13810   "&& 1"
13811   [(pc)]
13813   convert_float128_to_int (operands, <CODE>);
13814   DONE;
13816   [(set_attr "length" "8")
13817    (set_attr "type" "mftgpr,vecsimple,fpstore")])
13819 (define_insn_and_split "float<uns>_<mode>si2_hw"
13820   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13821         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13822    (clobber (match_scratch:V2DI 2 "=v,v"))]
13823   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13824   "#"
13825   "&& 1"
13826   [(pc)]
13828   convert_int_to_float128 (operands, <CODE>);
13829   DONE;
13831   [(set_attr "length" "8")
13832    (set_attr "type" "vecfloat")])
13834 (define_insn_and_split "float<uns>_<mode>di2_hw"
13835   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13836         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13837    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13838   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13839   "#"
13840   "&& 1"
13841   [(pc)]
13843   convert_int_to_float128 (operands, <CODE>);
13844   DONE;
13846   [(set_attr "length" "8")
13847    (set_attr "type" "vecfloat")])
13849 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13850 (define_insn "*xscvqp<su>wz_<mode>"
13851   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13852         (unspec:V2DI
13853          [(any_fix:SI
13854            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13855          UNSPEC_IEEE128_CONVERT))]
13856   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13857   "xscvqp<su>wz %0,%1"
13858   [(set_attr "type" "vecfloat")
13859    (set_attr "size" "128")])
13861 (define_insn "*xscvqp<su>dz_<mode>"
13862   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13863         (unspec:V2DI
13864          [(any_fix:DI
13865            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13866          UNSPEC_IEEE128_CONVERT))]
13867   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13868   "xscvqp<su>dz %0,%1"
13869   [(set_attr "type" "vecfloat")
13870    (set_attr "size" "128")])
13872 (define_insn "*xscv<su>dqp_<mode>"
13873   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13874         (any_float:IEEE128
13875          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13876                     UNSPEC_IEEE128_CONVERT)))]
13877   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13878   "xscv<su>dqp %0,%1"
13879   [(set_attr "type" "vecfloat")
13880    (set_attr "size" "128")])
13882 (define_insn "*ieee128_mfvsrd_64bit"
13883   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13884         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13885                    UNSPEC_IEEE128_MOVE))]
13886   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13887   "@
13888    mfvsrd %0,%x1
13889    stxsdx %x1,%y0
13890    xxlor %x0,%x1,%x1"
13891   [(set_attr "type" "mftgpr,fpstore,veclogical")])
13894 (define_insn "*ieee128_mfvsrd_32bit"
13895   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13896         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13897                    UNSPEC_IEEE128_MOVE))]
13898   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13899   "@
13900    stxsdx %x1,%y0
13901    xxlor %x0,%x1,%x1"
13902   [(set_attr "type" "fpstore,veclogical")])
13904 (define_insn "*ieee128_mfvsrwz"
13905   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13906         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13907                    UNSPEC_IEEE128_MOVE))]
13908   "TARGET_FLOAT128_HW"
13909   "@
13910    mfvsrwz %0,%x1
13911    stxsiwx %x1,%y0"
13912   [(set_attr "type" "mftgpr,fpstore")])
13914 ;; 0 says do sign-extension, 1 says zero-extension
13915 (define_insn "*ieee128_mtvsrw"
13916   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13917         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13918                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13919                      UNSPEC_IEEE128_MOVE))]
13920   "TARGET_FLOAT128_HW"
13921   "@
13922    mtvsrwa %x0,%1
13923    lxsiwax %x0,%y1
13924    mtvsrwz %x0,%1
13925    lxsiwzx %x0,%y1"
13926   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13929 (define_insn "*ieee128_mtvsrd_64bit"
13930   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13931         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13932                      UNSPEC_IEEE128_MOVE))]
13933   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13934   "@
13935    mtvsrd %x0,%1
13936    lxsdx %x0,%y1
13937    xxlor %x0,%x1,%x1"
13938   [(set_attr "type" "mffgpr,fpload,veclogical")])
13940 (define_insn "*ieee128_mtvsrd_32bit"
13941   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13942         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13943                      UNSPEC_IEEE128_MOVE))]
13944   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13945   "@
13946    lxsdx %x0,%y1
13947    xxlor %x0,%x1,%x1"
13948   [(set_attr "type" "fpload,veclogical")])
13950 ;; IEEE 128-bit instructions with round to odd semantics
13951 (define_insn "*trunc<mode>df2_odd"
13952   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13953         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13954                    UNSPEC_ROUND_TO_ODD))]
13955   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13956   "xscvqpdpo %0,%1"
13957   [(set_attr "type" "vecfloat")
13958    (set_attr "size" "128")])
13960 ;; IEEE 128-bit comparisons
13961 (define_insn "*cmp<mode>_hw"
13962   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13963         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13964                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13965   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13966    "xscmpuqp %0,%1,%2"
13967   [(set_attr "type" "veccmp")
13968    (set_attr "size" "128")])
13972 (include "sync.md")
13973 (include "vector.md")
13974 (include "vsx.md")
13975 (include "altivec.md")
13976 (include "spe.md")
13977 (include "dfp.md")
13978 (include "paired.md")
13979 (include "crypto.md")
13980 (include "htm.md")