[gcc]
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob46f73823392d8d1e8b1f58d4edcf460c0c1e640f
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   ])
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
158   [UNSPECV_BLOCK
159    UNSPECV_LL                   ; load-locked
160    UNSPECV_SC                   ; store-conditional
161    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
162    UNSPECV_EH_RR                ; eh_reg_restore
163    UNSPECV_ISYNC                ; isync instruction
164    UNSPECV_MFTB                 ; move from time base
165    UNSPECV_NLGR                 ; non-local goto receiver
166    UNSPECV_MFFS                 ; Move from FPSCR
167    UNSPECV_MTFSF                ; Move to FPSCR Fields
168    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
169   ])
172 ;; Define an insn type attribute.  This is used in function unit delay
173 ;; computations.
174 (define_attr "type"
175   "integer,two,three,
176    add,logical,shift,insert,
177    mul,halfmul,div,
178    exts,cntlz,popcnt,isel,
179    load,store,fpload,fpstore,vecload,vecstore,
180    cmp,
181    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
182    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
183    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
184    brinc,
185    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
186    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187    veclogical,veccmpfx,vecexts,vecmove,
188    htm,htmsimple,dfp"
189   (const_string "integer"))
191 ;; What data size does this instruction work on?
192 ;; This is used for insert, mul and others as necessary.
193 (define_attr "size" "8,16,32,64,128" (const_string "32"))
195 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
196 ;; This is used for add, logical, shift, exts, mul.
197 (define_attr "dot" "no,yes" (const_string "no"))
199 ;; Does this instruction sign-extend its result?
200 ;; This is used for load insns.
201 (define_attr "sign_extend" "no,yes" (const_string "no"))
203 ;; Does this instruction use indexed (that is, reg+reg) addressing?
204 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
205 ;; it is automatically set based on that.  If a load or store instruction
206 ;; has fewer than two operands it needs to set this attribute manually
207 ;; or the compiler will crash.
208 (define_attr "indexed" "no,yes"
209   (if_then_else (ior (match_operand 0 "indexed_address_mem")
210                      (match_operand 1 "indexed_address_mem"))
211                 (const_string "yes")
212                 (const_string "no")))
214 ;; Does this instruction use update addressing?
215 ;; This is used for load and store insns.  See the comments for "indexed".
216 (define_attr "update" "no,yes"
217   (if_then_else (ior (match_operand 0 "update_address_mem")
218                      (match_operand 1 "update_address_mem"))
219                 (const_string "yes")
220                 (const_string "no")))
222 ;; Is this instruction using operands[2] as shift amount, and can that be a
223 ;; register?
224 ;; This is used for shift insns.
225 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
227 ;; Is this instruction using a shift amount from a register?
228 ;; This is used for shift insns.
229 (define_attr "var_shift" "no,yes"
230   (if_then_else (and (eq_attr "type" "shift")
231                      (eq_attr "maybe_var_shift" "yes"))
232                 (if_then_else (match_operand 2 "gpc_reg_operand")
233                               (const_string "yes")
234                               (const_string "no"))
235                 (const_string "no")))
237 ;; Is copying of this instruction disallowed?
238 (define_attr "cannot_copy" "no,yes" (const_string "no"))
240 ;; Define floating point instruction sub-types for use with Xfpu.md
241 (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"))
243 ;; Length (in bytes).
244 ; '(pc)' in the following doesn't include the instruction itself; it is
245 ; calculated as if the instruction had zero size.
246 (define_attr "length" ""
247   (if_then_else (eq_attr "type" "branch")
248                 (if_then_else (and (ge (minus (match_dup 0) (pc))
249                                        (const_int -32768))
250                                    (lt (minus (match_dup 0) (pc))
251                                        (const_int 32764)))
252                               (const_int 4)
253                               (const_int 8))
254                 (const_int 4)))
256 ;; Processor type -- this attribute must exactly match the processor_type
257 ;; enumeration in rs6000-opts.h.
258 (define_attr "cpu"
259   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
260    ppc750,ppc7400,ppc7450,
261    ppc403,ppc405,ppc440,ppc476,
262    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
263    power4,power5,power6,power7,power8,power9,
264    rs64a,mpccore,cell,ppca2,titan"
265   (const (symbol_ref "rs6000_cpu_attr")))
268 ;; If this instruction is microcoded on the CELL processor
269 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
270 (define_attr "cell_micro" "not,conditional,always"
271   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
272                           (eq_attr "dot" "yes"))
273                      (and (eq_attr "type" "load")
274                           (eq_attr "sign_extend" "yes"))
275                      (and (eq_attr "type" "shift")
276                           (eq_attr "var_shift" "yes")))
277                 (const_string "always")
278                 (const_string "not")))
280 (automata_option "ndfa")
282 (include "rs64.md")
283 (include "mpc.md")
284 (include "40x.md")
285 (include "440.md")
286 (include "476.md")
287 (include "601.md")
288 (include "603.md")
289 (include "6xx.md")
290 (include "7xx.md")
291 (include "7450.md")
292 (include "8540.md")
293 (include "e300c2c3.md")
294 (include "e500mc.md")
295 (include "e500mc64.md")
296 (include "e5500.md")
297 (include "e6500.md")
298 (include "power4.md")
299 (include "power5.md")
300 (include "power6.md")
301 (include "power7.md")
302 (include "power8.md")
303 (include "power9.md")
304 (include "cell.md")
305 (include "xfpu.md")
306 (include "a2.md")
307 (include "titan.md")
309 (include "predicates.md")
310 (include "constraints.md")
312 (include "darwin.md")
315 ;; Mode iterators
317 ; This mode iterator allows :GPR to be used to indicate the allowable size
318 ; of whole values in GPRs.
319 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
321 ; Any supported integer mode.
322 (define_mode_iterator INT [QI HI SI DI TI PTI])
324 ; Any supported integer mode that fits in one register.
325 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
327 ; Everything we can extend QImode to.
328 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
330 ; Everything we can extend HImode to.
331 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
333 ; Everything we can extend SImode to.
334 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
336 ; QImode or HImode for small atomic ops
337 (define_mode_iterator QHI [QI HI])
339 ; QImode, HImode, SImode for fused ops only for GPR loads
340 (define_mode_iterator QHSI [QI HI SI])
342 ; HImode or SImode for sign extended fusion ops
343 (define_mode_iterator HSI [HI SI])
345 ; SImode or DImode, even if DImode doesn't fit in GPRs.
346 (define_mode_iterator SDI [SI DI])
348 ; Types that can be fused with an ADDIS instruction to load or store a GPR
349 ; register that has reg+offset addressing.
350 (define_mode_iterator GPR_FUSION [QI
351                                   HI
352                                   SI
353                                   (DI   "TARGET_POWERPC64")
354                                   SF
355                                   (DF   "TARGET_POWERPC64")])
357 ; Types that can be fused with an ADDIS instruction to load or store a FPR
358 ; register that has reg+offset addressing.
359 (define_mode_iterator FPR_FUSION [DI SF DF])
361 ; The size of a pointer.  Also, the size of the value that a record-condition
362 ; (one with a '.') will compare; and the size used for arithmetic carries.
363 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
365 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
366 ; PTImode is GPR only)
367 (define_mode_iterator TI2 [TI PTI])
369 ; Any hardware-supported floating-point mode
370 (define_mode_iterator FP [
371   (SF "TARGET_HARD_FLOAT 
372    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
373   (DF "TARGET_HARD_FLOAT 
374    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
375   (TF "TARGET_HARD_FLOAT
376    && (TARGET_FPRS || TARGET_E500_DOUBLE)
377    && TARGET_LONG_DOUBLE_128")
378   (IF "TARGET_FLOAT128")
379   (KF "TARGET_FLOAT128")
380   (DD "TARGET_DFP")
381   (TD "TARGET_DFP")])
383 ; Any fma capable floating-point mode.
384 (define_mode_iterator FMA_F [
385   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
386   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
387        || VECTOR_UNIT_VSX_P (DFmode)")
388   (V2SF "TARGET_PAIRED_FLOAT")
389   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
390   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
391   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
392   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
393   ])
395 ; Floating point move iterators to combine binary and decimal moves
396 (define_mode_iterator FMOVE32 [SF SD])
397 (define_mode_iterator FMOVE64 [DF DD])
398 (define_mode_iterator FMOVE64X [DI DF DD])
399 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
400                                 (IF "TARGET_LONG_DOUBLE_128")
401                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
403 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
404                                     (IF "FLOAT128_2REG_P (IFmode)")
405                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
407 ; Iterators for 128 bit types for direct move
408 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
409                                     (V16QI "")
410                                     (V8HI  "")
411                                     (V4SI  "")
412                                     (V4SF  "")
413                                     (V2DI  "")
414                                     (V2DF  "")
415                                     (V1TI  "")
416                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
417                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
419 ; Iterator for 128-bit VSX types for pack/unpack
420 (define_mode_iterator FMOVE128_VSX [V1TI KF])
422 ; Whether a floating point move is ok, don't allow SD without hardware FP
423 (define_mode_attr fmove_ok [(SF "")
424                             (DF "")
425                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
426                             (DD "")])
428 ; Convert REAL_VALUE to the appropriate bits
429 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
430                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
431                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
432                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
434 ; Whether 0.0 has an all-zero bit pattern
435 (define_mode_attr zero_fp [(SF "j")
436                            (DF "j")
437                            (TF "j")
438                            (IF "j")
439                            (KF "j")
440                            (SD "wn")
441                            (DD "wn")
442                            (TD "wn")])
444 ; Definitions for load to 32-bit fpr register
445 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
446 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
447 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
448 (define_mode_attr f32_lm2 [(SF "o")               (SD "wn")])
449 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
450 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
451 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
453 ; Definitions for store from 32-bit fpr register
454 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
455 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
456 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
457 (define_mode_attr f32_sm2 [(SF "o")                (SD "wn")])
458 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
459 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
460 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwzx %x1,%y0")])
462 ; Definitions for 32-bit fpr direct move
463 ; At present, the decimal modes are not allowed in the traditional altivec
464 ; registers, so restrict the constraints to just the traditional FPRs.
465 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
467 ; Definitions for 32-bit VSX
468 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
470 ; Definitions for 32-bit use of altivec registers
471 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
473 ; Definitions for 64-bit VSX
474 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
476 ; Definitions for 64-bit direct move
477 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
479 ; Definitions for 64-bit use of altivec registers
480 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
482 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
483 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
485 ; These modes do not fit in integer registers in 32-bit mode.
486 ; but on e500v2, the gpr are 64 bit registers
487 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
489 ; Iterator for reciprocal estimate instructions
490 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
492 ; Iterator for just SF/DF
493 (define_mode_iterator SFDF [SF DF])
495 ; Like SFDF, but a different name to match conditional move where the
496 ; comparison operands may be a different mode than the input operands.
497 (define_mode_iterator SFDF2 [SF DF])
499 ; Iterator for 128-bit floating point that uses the IBM double-double format
500 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
501                               (TF "FLOAT128_IBM_P (TFmode)")])
503 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
504 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
505                                (TF "FLOAT128_IEEE_P (TFmode)")])
507 ; Iterator for 128-bit floating point
508 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
509                                 (IF "TARGET_FLOAT128")
510                                 (TF "TARGET_LONG_DOUBLE_128")])
512 ; Iterator for signbit on 64-bit machines with direct move
513 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
514                                (TF "FLOAT128_VECTOR_P (TFmode)")])
516 (define_mode_attr Fsignbit      [(KF "wa")
517                                  (TF "wa")])
519 ; Iterator for ISA 3.0 supported floating point types
520 (define_mode_iterator FP_ISA3 [SF
521                                DF
522                                (KF "FLOAT128_IEEE_P (KFmode)")
523                                (TF "FLOAT128_IEEE_P (TFmode)")])
525 ; SF/DF suffix for traditional floating instructions
526 (define_mode_attr Ftrad         [(SF "s") (DF "")])
528 ; SF/DF suffix for VSX instructions
529 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
531 ; SF/DF constraint for arithmetic on traditional floating point registers
532 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
534 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
535 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
536 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
537 ; format.
538 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
540 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
541 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
542 ; instructions added in ISA 2.07 (power8)
543 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
545 ; SF/DF constraint for arithmetic on altivec registers
546 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
548 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
549 (define_mode_attr Fs            [(SF "s")  (DF "d")])
551 ; FRE/FRES support
552 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
553 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
555 ; Conditional returns.
556 (define_code_iterator any_return [return simple_return])
557 (define_code_attr return_pred [(return "direct_return ()")
558                                (simple_return "1")])
559 (define_code_attr return_str [(return "") (simple_return "simple_")])
561 ; Logical operators.
562 (define_code_iterator iorxor [ior xor])
564 ; Signed/unsigned variants of ops.
565 (define_code_iterator any_extend        [sign_extend zero_extend])
566 (define_code_iterator any_fix           [fix unsigned_fix])
567 (define_code_iterator any_float         [float unsigned_float])
569 (define_code_attr u  [(sign_extend      "")
570                       (zero_extend      "u")])
572 (define_code_attr su [(sign_extend      "s")
573                       (zero_extend      "u")
574                       (fix              "s")
575                       (unsigned_fix     "s")
576                       (float            "s")
577                       (unsigned_float   "u")])
579 (define_code_attr az [(sign_extend      "a")
580                       (zero_extend      "z")
581                       (fix              "a")
582                       (unsigned_fix     "z")
583                       (float            "a")
584                       (unsigned_float   "z")])
586 (define_code_attr uns [(fix             "")
587                        (unsigned_fix    "uns")
588                        (float           "")
589                        (unsigned_float  "uns")])
591 ; Various instructions that come in SI and DI forms.
592 ; A generic w/d attribute, for things like cmpw/cmpd.
593 (define_mode_attr wd [(QI    "b")
594                       (HI    "h")
595                       (SI    "w")
596                       (DI    "d")
597                       (V16QI "b")
598                       (V8HI  "h")
599                       (V4SI  "w")
600                       (V2DI  "d")
601                       (V1TI  "q")
602                       (TI    "q")])
604 ;; How many bits in this mode?
605 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
607 ; DImode bits
608 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
610 ;; ISEL/ISEL64 target selection
611 (define_mode_attr sel [(SI "") (DI "64")])
613 ;; Bitmask for shift instructions
614 (define_mode_attr hH [(SI "h") (DI "H")])
616 ;; A mode twice the size of the given mode
617 (define_mode_attr dmode [(SI "di") (DI "ti")])
618 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
620 ;; Suffix for reload patterns
621 (define_mode_attr ptrsize [(SI "32bit")
622                            (DI "64bit")])
624 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
625                             (DI "TARGET_64BIT")])
627 (define_mode_attr mptrsize [(SI "si")
628                             (DI "di")])
630 (define_mode_attr ptrload [(SI "lwz")
631                            (DI "ld")])
633 (define_mode_attr ptrm [(SI "m")
634                         (DI "Y")])
636 (define_mode_attr rreg [(SF   "f")
637                         (DF   "ws")
638                         (TF   "f")
639                         (TD   "f")
640                         (V4SF "wf")
641                         (V2DF "wd")])
643 (define_mode_attr rreg2 [(SF   "f")
644                          (DF   "d")])
646 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
647                                  (DF "TARGET_FCFID")])
649 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
650                                 (DF "TARGET_E500_DOUBLE")])
652 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
653                                 (DF "TARGET_DOUBLE_FLOAT")])
655 ;; Mode iterator for logical operations on 128-bit types
656 (define_mode_iterator BOOL_128          [TI
657                                          PTI
658                                          (V16QI "TARGET_ALTIVEC")
659                                          (V8HI  "TARGET_ALTIVEC")
660                                          (V4SI  "TARGET_ALTIVEC")
661                                          (V4SF  "TARGET_ALTIVEC")
662                                          (V2DI  "TARGET_ALTIVEC")
663                                          (V2DF  "TARGET_ALTIVEC")
664                                          (V1TI  "TARGET_ALTIVEC")])
666 ;; For the GPRs we use 3 constraints for register outputs, two that are the
667 ;; same as the output register, and a third where the output register is an
668 ;; early clobber, so we don't have to deal with register overlaps.  For the
669 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
670 ;; either.
672 ;; Mode attribute for boolean operation register constraints for output
673 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
674                                          (PTI   "&r,r,r")
675                                          (V16QI "wa,v,&?r,?r,?r")
676                                          (V8HI  "wa,v,&?r,?r,?r")
677                                          (V4SI  "wa,v,&?r,?r,?r")
678                                          (V4SF  "wa,v,&?r,?r,?r")
679                                          (V2DI  "wa,v,&?r,?r,?r")
680                                          (V2DF  "wa,v,&?r,?r,?r")
681                                          (V1TI  "wa,v,&?r,?r,?r")])
683 ;; Mode attribute for boolean operation register constraints for operand1
684 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
685                                          (PTI   "r,0,r")
686                                          (V16QI "wa,v,r,0,r")
687                                          (V8HI  "wa,v,r,0,r")
688                                          (V4SI  "wa,v,r,0,r")
689                                          (V4SF  "wa,v,r,0,r")
690                                          (V2DI  "wa,v,r,0,r")
691                                          (V2DF  "wa,v,r,0,r")
692                                          (V1TI  "wa,v,r,0,r")])
694 ;; Mode attribute for boolean operation register constraints for operand2
695 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
696                                          (PTI   "r,r,0")
697                                          (V16QI "wa,v,r,r,0")
698                                          (V8HI  "wa,v,r,r,0")
699                                          (V4SI  "wa,v,r,r,0")
700                                          (V4SF  "wa,v,r,r,0")
701                                          (V2DI  "wa,v,r,r,0")
702                                          (V2DF  "wa,v,r,r,0")
703                                          (V1TI  "wa,v,r,r,0")])
705 ;; Mode attribute for boolean operation register constraints for operand1
706 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
707 ;; is used for operand1 or operand2
708 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
709                                          (PTI   "r,0,0")
710                                          (V16QI "wa,v,r,0,0")
711                                          (V8HI  "wa,v,r,0,0")
712                                          (V4SI  "wa,v,r,0,0")
713                                          (V4SF  "wa,v,r,0,0")
714                                          (V2DI  "wa,v,r,0,0")
715                                          (V2DF  "wa,v,r,0,0")
716                                          (V1TI  "wa,v,r,0,0")])
718 ;; Reload iterator for creating the function to allocate a base register to
719 ;; supplement addressing modes.
720 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
721                               SF SD SI DF DD DI TI PTI KF IF TF])
723 ;; Iterate over smin, smax
724 (define_code_iterator fp_minmax [smin smax])
726 (define_code_attr     minmax    [(smin "min")
727                                  (smax "max")])
729 (define_code_attr     SMINMAX   [(smin "SMIN")
730                                  (smax "SMAX")])
733 ;; Start with fixed-point load and store insns.  Here we put only the more
734 ;; complex forms.  Basic data transfer is done later.
736 (define_insn "zero_extendqi<mode>2"
737   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
738         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
739   ""
740   "@
741    lbz%U1%X1 %0,%1
742    rlwinm %0,%1,0,0xff"
743   [(set_attr "type" "load,shift")])
745 (define_insn_and_split "*zero_extendqi<mode>2_dot"
746   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
747         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
748                     (const_int 0)))
749    (clobber (match_scratch:EXTQI 0 "=r,r"))]
750   "rs6000_gen_cell_microcode"
751   "@
752    andi. %0,%1,0xff
753    #"
754   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
755   [(set (match_dup 0)
756         (zero_extend:EXTQI (match_dup 1)))
757    (set (match_dup 2)
758         (compare:CC (match_dup 0)
759                     (const_int 0)))]
760   ""
761   [(set_attr "type" "logical")
762    (set_attr "dot" "yes")
763    (set_attr "length" "4,8")])
765 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
766   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
767         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
768                     (const_int 0)))
769    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
770         (zero_extend:EXTQI (match_dup 1)))]
771   "rs6000_gen_cell_microcode"
772   "@
773    andi. %0,%1,0xff
774    #"
775   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
776   [(set (match_dup 0)
777         (zero_extend:EXTQI (match_dup 1)))
778    (set (match_dup 2)
779         (compare:CC (match_dup 0)
780                     (const_int 0)))]
781   ""
782   [(set_attr "type" "logical")
783    (set_attr "dot" "yes")
784    (set_attr "length" "4,8")])
787 (define_insn "zero_extendhi<mode>2"
788   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
789         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
790   ""
791   "@
792    lhz%U1%X1 %0,%1
793    rlwinm %0,%1,0,0xffff"
794   [(set_attr "type" "load,shift")])
796 (define_insn_and_split "*zero_extendhi<mode>2_dot"
797   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
798         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
799                     (const_int 0)))
800    (clobber (match_scratch:EXTHI 0 "=r,r"))]
801   "rs6000_gen_cell_microcode"
802   "@
803    andi. %0,%1,0xffff
804    #"
805   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
806   [(set (match_dup 0)
807         (zero_extend:EXTHI (match_dup 1)))
808    (set (match_dup 2)
809         (compare:CC (match_dup 0)
810                     (const_int 0)))]
811   ""
812   [(set_attr "type" "logical")
813    (set_attr "dot" "yes")
814    (set_attr "length" "4,8")])
816 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
817   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
818         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
819                     (const_int 0)))
820    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
821         (zero_extend:EXTHI (match_dup 1)))]
822   "rs6000_gen_cell_microcode"
823   "@
824    andi. %0,%1,0xffff
825    #"
826   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
827   [(set (match_dup 0)
828         (zero_extend:EXTHI (match_dup 1)))
829    (set (match_dup 2)
830         (compare:CC (match_dup 0)
831                     (const_int 0)))]
832   ""
833   [(set_attr "type" "logical")
834    (set_attr "dot" "yes")
835    (set_attr "length" "4,8")])
838 (define_insn "zero_extendsi<mode>2"
839   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
840         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
841   ""
842   "@
843    lwz%U1%X1 %0,%1
844    rldicl %0,%1,0,32
845    mtvsrwz %x0,%1
846    lfiwzx %0,%y1
847    lxsiwzx %x0,%y1"
848   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
850 (define_insn_and_split "*zero_extendsi<mode>2_dot"
851   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
852         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
853                     (const_int 0)))
854    (clobber (match_scratch:EXTSI 0 "=r,r"))]
855   "rs6000_gen_cell_microcode"
856   "@
857    rldicl. %0,%1,0,32
858    #"
859   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
860   [(set (match_dup 0)
861         (zero_extend:DI (match_dup 1)))
862    (set (match_dup 2)
863         (compare:CC (match_dup 0)
864                     (const_int 0)))]
865   ""
866   [(set_attr "type" "shift")
867    (set_attr "dot" "yes")
868    (set_attr "length" "4,8")])
870 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
871   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
872         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
873                     (const_int 0)))
874    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
875         (zero_extend:EXTSI (match_dup 1)))]
876   "rs6000_gen_cell_microcode"
877   "@
878    rldicl. %0,%1,0,32
879    #"
880   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
881   [(set (match_dup 0)
882         (zero_extend:EXTSI (match_dup 1)))
883    (set (match_dup 2)
884         (compare:CC (match_dup 0)
885                     (const_int 0)))]
886   ""
887   [(set_attr "type" "shift")
888    (set_attr "dot" "yes")
889    (set_attr "length" "4,8")])
892 (define_insn "extendqi<mode>2"
893   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
894         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
895   ""
896   "extsb %0,%1"
897   [(set_attr "type" "exts")])
899 (define_insn_and_split "*extendqi<mode>2_dot"
900   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
901         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
902                     (const_int 0)))
903    (clobber (match_scratch:EXTQI 0 "=r,r"))]
904   "rs6000_gen_cell_microcode"
905   "@
906    extsb. %0,%1
907    #"
908   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
909   [(set (match_dup 0)
910         (sign_extend:EXTQI (match_dup 1)))
911    (set (match_dup 2)
912         (compare:CC (match_dup 0)
913                     (const_int 0)))]
914   ""
915   [(set_attr "type" "exts")
916    (set_attr "dot" "yes")
917    (set_attr "length" "4,8")])
919 (define_insn_and_split "*extendqi<mode>2_dot2"
920   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
921         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
922                     (const_int 0)))
923    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
924         (sign_extend:EXTQI (match_dup 1)))]
925   "rs6000_gen_cell_microcode"
926   "@
927    extsb. %0,%1
928    #"
929   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
930   [(set (match_dup 0)
931         (sign_extend:EXTQI (match_dup 1)))
932    (set (match_dup 2)
933         (compare:CC (match_dup 0)
934                     (const_int 0)))]
935   ""
936   [(set_attr "type" "exts")
937    (set_attr "dot" "yes")
938    (set_attr "length" "4,8")])
941 (define_expand "extendhi<mode>2"
942   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
943         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
944   ""
945   "")
947 (define_insn "*extendhi<mode>2"
948   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
949         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
950   "rs6000_gen_cell_microcode"
951   "@
952    lha%U1%X1 %0,%1
953    extsh %0,%1"
954   [(set_attr "type" "load,exts")
955    (set_attr "sign_extend" "yes")])
957 (define_insn "*extendhi<mode>2_noload"
958   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
959         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
960   "!rs6000_gen_cell_microcode"
961   "extsh %0,%1"
962   [(set_attr "type" "exts")])
964 (define_insn_and_split "*extendhi<mode>2_dot"
965   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
966         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
967                     (const_int 0)))
968    (clobber (match_scratch:EXTHI 0 "=r,r"))]
969   "rs6000_gen_cell_microcode"
970   "@
971    extsh. %0,%1
972    #"
973   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
974   [(set (match_dup 0)
975         (sign_extend:EXTHI (match_dup 1)))
976    (set (match_dup 2)
977         (compare:CC (match_dup 0)
978                     (const_int 0)))]
979   ""
980   [(set_attr "type" "exts")
981    (set_attr "dot" "yes")
982    (set_attr "length" "4,8")])
984 (define_insn_and_split "*extendhi<mode>2_dot2"
985   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
986         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
987                     (const_int 0)))
988    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
989         (sign_extend:EXTHI (match_dup 1)))]
990   "rs6000_gen_cell_microcode"
991   "@
992    extsh. %0,%1
993    #"
994   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
995   [(set (match_dup 0)
996         (sign_extend:EXTHI (match_dup 1)))
997    (set (match_dup 2)
998         (compare:CC (match_dup 0)
999                     (const_int 0)))]
1000   ""
1001   [(set_attr "type" "exts")
1002    (set_attr "dot" "yes")
1003    (set_attr "length" "4,8")])
1006 (define_insn "extendsi<mode>2"
1007   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
1008         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
1009   ""
1010   "@
1011    lwa%U1%X1 %0,%1
1012    extsw %0,%1
1013    mtvsrwa %x0,%1
1014    lfiwax %0,%y1
1015    lxsiwax %x0,%y1"
1016   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
1017    (set_attr "sign_extend" "yes")])
1019 (define_insn_and_split "*extendsi<mode>2_dot"
1020   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1021         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1022                     (const_int 0)))
1023    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1024   "rs6000_gen_cell_microcode"
1025   "@
1026    extsw. %0,%1
1027    #"
1028   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1029   [(set (match_dup 0)
1030         (sign_extend:EXTSI (match_dup 1)))
1031    (set (match_dup 2)
1032         (compare:CC (match_dup 0)
1033                     (const_int 0)))]
1034   ""
1035   [(set_attr "type" "exts")
1036    (set_attr "dot" "yes")
1037    (set_attr "length" "4,8")])
1039 (define_insn_and_split "*extendsi<mode>2_dot2"
1040   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1041         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1042                     (const_int 0)))
1043    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1044         (sign_extend:EXTSI (match_dup 1)))]
1045   "rs6000_gen_cell_microcode"
1046   "@
1047    extsw. %0,%1
1048    #"
1049   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1050   [(set (match_dup 0)
1051         (sign_extend:EXTSI (match_dup 1)))
1052    (set (match_dup 2)
1053         (compare:CC (match_dup 0)
1054                     (const_int 0)))]
1055   ""
1056   [(set_attr "type" "exts")
1057    (set_attr "dot" "yes")
1058    (set_attr "length" "4,8")])
1060 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1062 (define_insn "*macchwc"
1063   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1064         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1065                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1066                                        (const_int 16))
1067                                       (sign_extend:SI
1068                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1069                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1070                     (const_int 0)))
1071    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1072         (plus:SI (mult:SI (ashiftrt:SI
1073                            (match_dup 2)
1074                            (const_int 16))
1075                           (sign_extend:SI
1076                            (match_dup 1)))
1077                  (match_dup 4)))]
1078   "TARGET_MULHW"
1079   "macchw. %0,%1,%2"
1080   [(set_attr "type" "halfmul")])
1082 (define_insn "*macchw"
1083   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1084         (plus:SI (mult:SI (ashiftrt:SI
1085                            (match_operand:SI 2 "gpc_reg_operand" "r")
1086                            (const_int 16))
1087                           (sign_extend:SI
1088                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1089                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1090   "TARGET_MULHW"
1091   "macchw %0,%1,%2"
1092   [(set_attr "type" "halfmul")])
1094 (define_insn "*macchwuc"
1095   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1096         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1097                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1098                                        (const_int 16))
1099                                       (zero_extend:SI
1100                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1101                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1102                     (const_int 0)))
1103    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1104         (plus:SI (mult:SI (lshiftrt:SI
1105                            (match_dup 2)
1106                            (const_int 16))
1107                           (zero_extend:SI
1108                            (match_dup 1)))
1109                  (match_dup 4)))]
1110   "TARGET_MULHW"
1111   "macchwu. %0,%1,%2"
1112   [(set_attr "type" "halfmul")])
1114 (define_insn "*macchwu"
1115   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1116         (plus:SI (mult:SI (lshiftrt:SI
1117                            (match_operand:SI 2 "gpc_reg_operand" "r")
1118                            (const_int 16))
1119                           (zero_extend:SI
1120                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1121                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1122   "TARGET_MULHW"
1123   "macchwu %0,%1,%2"
1124   [(set_attr "type" "halfmul")])
1126 (define_insn "*machhwc"
1127   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1128         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1129                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1130                                        (const_int 16))
1131                                       (ashiftrt:SI
1132                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1133                                        (const_int 16)))
1134                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1135                     (const_int 0)))
1136    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137         (plus:SI (mult:SI (ashiftrt:SI
1138                            (match_dup 1)
1139                            (const_int 16))
1140                           (ashiftrt:SI
1141                            (match_dup 2)
1142                            (const_int 16)))
1143                  (match_dup 4)))]
1144   "TARGET_MULHW"
1145   "machhw. %0,%1,%2"
1146   [(set_attr "type" "halfmul")])
1148 (define_insn "*machhw"
1149   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1150         (plus:SI (mult:SI (ashiftrt:SI
1151                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1152                            (const_int 16))
1153                           (ashiftrt:SI
1154                            (match_operand:SI 2 "gpc_reg_operand" "r")
1155                            (const_int 16)))
1156                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1157   "TARGET_MULHW"
1158   "machhw %0,%1,%2"
1159   [(set_attr "type" "halfmul")])
1161 (define_insn "*machhwuc"
1162   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1163         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1164                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1165                                        (const_int 16))
1166                                       (lshiftrt:SI
1167                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1168                                        (const_int 16)))
1169                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1170                     (const_int 0)))
1171    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1172         (plus:SI (mult:SI (lshiftrt:SI
1173                            (match_dup 1)
1174                            (const_int 16))
1175                           (lshiftrt:SI
1176                            (match_dup 2)
1177                            (const_int 16)))
1178                  (match_dup 4)))]
1179   "TARGET_MULHW"
1180   "machhwu. %0,%1,%2"
1181   [(set_attr "type" "halfmul")])
1183 (define_insn "*machhwu"
1184   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1185         (plus:SI (mult:SI (lshiftrt:SI
1186                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1187                            (const_int 16))
1188                           (lshiftrt:SI
1189                            (match_operand:SI 2 "gpc_reg_operand" "r")
1190                            (const_int 16)))
1191                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1192   "TARGET_MULHW"
1193   "machhwu %0,%1,%2"
1194   [(set_attr "type" "halfmul")])
1196 (define_insn "*maclhwc"
1197   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1198         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1199                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1200                                       (sign_extend:SI
1201                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1202                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1203                     (const_int 0)))
1204    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1205         (plus:SI (mult:SI (sign_extend:SI
1206                            (match_dup 1))
1207                           (sign_extend:SI
1208                            (match_dup 2)))
1209                  (match_dup 4)))]
1210   "TARGET_MULHW"
1211   "maclhw. %0,%1,%2"
1212   [(set_attr "type" "halfmul")])
1214 (define_insn "*maclhw"
1215   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1216         (plus:SI (mult:SI (sign_extend:SI
1217                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1218                           (sign_extend:SI
1219                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1220                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1221   "TARGET_MULHW"
1222   "maclhw %0,%1,%2"
1223   [(set_attr "type" "halfmul")])
1225 (define_insn "*maclhwuc"
1226   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1227         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1228                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1229                                       (zero_extend:SI
1230                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1231                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1232                     (const_int 0)))
1233    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1234         (plus:SI (mult:SI (zero_extend:SI
1235                            (match_dup 1))
1236                           (zero_extend:SI
1237                            (match_dup 2)))
1238                  (match_dup 4)))]
1239   "TARGET_MULHW"
1240   "maclhwu. %0,%1,%2"
1241   [(set_attr "type" "halfmul")])
1243 (define_insn "*maclhwu"
1244   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245         (plus:SI (mult:SI (zero_extend:SI
1246                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1247                           (zero_extend:SI
1248                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1249                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1250   "TARGET_MULHW"
1251   "maclhwu %0,%1,%2"
1252   [(set_attr "type" "halfmul")])
1254 (define_insn "*nmacchwc"
1255   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1256         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1257                               (mult:SI (ashiftrt:SI
1258                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1259                                         (const_int 16))
1260                                        (sign_extend:SI
1261                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1262                     (const_int 0)))
1263    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264         (minus:SI (match_dup 4)
1265                   (mult:SI (ashiftrt:SI
1266                             (match_dup 2)
1267                             (const_int 16))
1268                            (sign_extend:SI
1269                             (match_dup 1)))))]
1270   "TARGET_MULHW"
1271   "nmacchw. %0,%1,%2"
1272   [(set_attr "type" "halfmul")])
1274 (define_insn "*nmacchw"
1275   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1277                   (mult:SI (ashiftrt:SI
1278                             (match_operand:SI 2 "gpc_reg_operand" "r")
1279                             (const_int 16))
1280                            (sign_extend:SI
1281                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1282   "TARGET_MULHW"
1283   "nmacchw %0,%1,%2"
1284   [(set_attr "type" "halfmul")])
1286 (define_insn "*nmachhwc"
1287   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1288         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1289                               (mult:SI (ashiftrt:SI
1290                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1291                                         (const_int 16))
1292                                        (ashiftrt:SI
1293                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1294                                         (const_int 16))))
1295                     (const_int 0)))
1296    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1297         (minus:SI (match_dup 4)
1298                   (mult:SI (ashiftrt:SI
1299                             (match_dup 1)
1300                             (const_int 16))
1301                            (ashiftrt:SI
1302                             (match_dup 2)
1303                             (const_int 16)))))]
1304   "TARGET_MULHW"
1305   "nmachhw. %0,%1,%2"
1306   [(set_attr "type" "halfmul")])
1308 (define_insn "*nmachhw"
1309   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1310         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1311                   (mult:SI (ashiftrt:SI
1312                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1313                             (const_int 16))
1314                            (ashiftrt:SI
1315                             (match_operand:SI 2 "gpc_reg_operand" "r")
1316                             (const_int 16)))))]
1317   "TARGET_MULHW"
1318   "nmachhw %0,%1,%2"
1319   [(set_attr "type" "halfmul")])
1321 (define_insn "*nmaclhwc"
1322   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1323         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1324                               (mult:SI (sign_extend:SI
1325                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1326                                        (sign_extend:SI
1327                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1328                     (const_int 0)))
1329    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330         (minus:SI (match_dup 4)
1331                   (mult:SI (sign_extend:SI
1332                             (match_dup 1))
1333                            (sign_extend:SI
1334                             (match_dup 2)))))]
1335   "TARGET_MULHW"
1336   "nmaclhw. %0,%1,%2"
1337   [(set_attr "type" "halfmul")])
1339 (define_insn "*nmaclhw"
1340   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1342                   (mult:SI (sign_extend:SI
1343                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1344                            (sign_extend:SI
1345                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1346   "TARGET_MULHW"
1347   "nmaclhw %0,%1,%2"
1348   [(set_attr "type" "halfmul")])
1350 (define_insn "*mulchwc"
1351   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1352         (compare:CC (mult:SI (ashiftrt:SI
1353                               (match_operand:SI 2 "gpc_reg_operand" "r")
1354                               (const_int 16))
1355                              (sign_extend:SI
1356                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1357                     (const_int 0)))
1358    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359         (mult:SI (ashiftrt:SI
1360                   (match_dup 2)
1361                   (const_int 16))
1362                  (sign_extend:SI
1363                   (match_dup 1))))]
1364   "TARGET_MULHW"
1365   "mulchw. %0,%1,%2"
1366   [(set_attr "type" "halfmul")])
1368 (define_insn "*mulchw"
1369   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1370         (mult:SI (ashiftrt:SI
1371                   (match_operand:SI 2 "gpc_reg_operand" "r")
1372                   (const_int 16))
1373                  (sign_extend:SI
1374                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1375   "TARGET_MULHW"
1376   "mulchw %0,%1,%2"
1377   [(set_attr "type" "halfmul")])
1379 (define_insn "*mulchwuc"
1380   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1381         (compare:CC (mult:SI (lshiftrt:SI
1382                               (match_operand:SI 2 "gpc_reg_operand" "r")
1383                               (const_int 16))
1384                              (zero_extend:SI
1385                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1386                     (const_int 0)))
1387    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1388         (mult:SI (lshiftrt:SI
1389                   (match_dup 2)
1390                   (const_int 16))
1391                  (zero_extend:SI
1392                   (match_dup 1))))]
1393   "TARGET_MULHW"
1394   "mulchwu. %0,%1,%2"
1395   [(set_attr "type" "halfmul")])
1397 (define_insn "*mulchwu"
1398   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399         (mult:SI (lshiftrt:SI
1400                   (match_operand:SI 2 "gpc_reg_operand" "r")
1401                   (const_int 16))
1402                  (zero_extend:SI
1403                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1404   "TARGET_MULHW"
1405   "mulchwu %0,%1,%2"
1406   [(set_attr "type" "halfmul")])
1408 (define_insn "*mulhhwc"
1409   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1410         (compare:CC (mult:SI (ashiftrt:SI
1411                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1412                               (const_int 16))
1413                              (ashiftrt:SI
1414                               (match_operand:SI 2 "gpc_reg_operand" "r")
1415                               (const_int 16)))
1416                     (const_int 0)))
1417    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1418         (mult:SI (ashiftrt:SI
1419                   (match_dup 1)
1420                   (const_int 16))
1421                  (ashiftrt:SI
1422                   (match_dup 2)
1423                   (const_int 16))))]
1424   "TARGET_MULHW"
1425   "mulhhw. %0,%1,%2"
1426   [(set_attr "type" "halfmul")])
1428 (define_insn "*mulhhw"
1429   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1430         (mult:SI (ashiftrt:SI
1431                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1432                   (const_int 16))
1433                  (ashiftrt:SI
1434                   (match_operand:SI 2 "gpc_reg_operand" "r")
1435                   (const_int 16))))]
1436   "TARGET_MULHW"
1437   "mulhhw %0,%1,%2"
1438   [(set_attr "type" "halfmul")])
1440 (define_insn "*mulhhwuc"
1441   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1442         (compare:CC (mult:SI (lshiftrt:SI
1443                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1444                               (const_int 16))
1445                              (lshiftrt:SI
1446                               (match_operand:SI 2 "gpc_reg_operand" "r")
1447                               (const_int 16)))
1448                     (const_int 0)))
1449    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1450         (mult:SI (lshiftrt:SI
1451                   (match_dup 1)
1452                   (const_int 16))
1453                  (lshiftrt:SI
1454                   (match_dup 2)
1455                   (const_int 16))))]
1456   "TARGET_MULHW"
1457   "mulhhwu. %0,%1,%2"
1458   [(set_attr "type" "halfmul")])
1460 (define_insn "*mulhhwu"
1461   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1462         (mult:SI (lshiftrt:SI
1463                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1464                   (const_int 16))
1465                  (lshiftrt:SI
1466                   (match_operand:SI 2 "gpc_reg_operand" "r")
1467                   (const_int 16))))]
1468   "TARGET_MULHW"
1469   "mulhhwu %0,%1,%2"
1470   [(set_attr "type" "halfmul")])
1472 (define_insn "*mullhwc"
1473   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1474         (compare:CC (mult:SI (sign_extend:SI
1475                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1476                              (sign_extend:SI
1477                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1478                     (const_int 0)))
1479    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1480         (mult:SI (sign_extend:SI
1481                   (match_dup 1))
1482                  (sign_extend:SI
1483                   (match_dup 2))))]
1484   "TARGET_MULHW"
1485   "mullhw. %0,%1,%2"
1486   [(set_attr "type" "halfmul")])
1488 (define_insn "*mullhw"
1489   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1490         (mult:SI (sign_extend:SI
1491                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1492                  (sign_extend:SI
1493                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1494   "TARGET_MULHW"
1495   "mullhw %0,%1,%2"
1496   [(set_attr "type" "halfmul")])
1498 (define_insn "*mullhwuc"
1499   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1500         (compare:CC (mult:SI (zero_extend:SI
1501                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1502                              (zero_extend:SI
1503                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1504                     (const_int 0)))
1505    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1506         (mult:SI (zero_extend:SI
1507                   (match_dup 1))
1508                  (zero_extend:SI
1509                   (match_dup 2))))]
1510   "TARGET_MULHW"
1511   "mullhwu. %0,%1,%2"
1512   [(set_attr "type" "halfmul")])
1514 (define_insn "*mullhwu"
1515   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1516         (mult:SI (zero_extend:SI
1517                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1518                  (zero_extend:SI
1519                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1520   "TARGET_MULHW"
1521   "mullhwu %0,%1,%2"
1522   [(set_attr "type" "halfmul")])
1524 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1525 (define_insn "dlmzb"
1526   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1527         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1528                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1529                    UNSPEC_DLMZB_CR))
1530    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531         (unspec:SI [(match_dup 1)
1532                     (match_dup 2)]
1533                    UNSPEC_DLMZB))]
1534   "TARGET_DLMZB"
1535   "dlmzb. %0,%1,%2")
1537 (define_expand "strlensi"
1538   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1539         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1540                     (match_operand:QI 2 "const_int_operand" "")
1541                     (match_operand 3 "const_int_operand" "")]
1542                    UNSPEC_DLMZB_STRLEN))
1543    (clobber (match_scratch:CC 4 "=x"))]
1544   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1546   rtx result = operands[0];
1547   rtx src = operands[1];
1548   rtx search_char = operands[2];
1549   rtx align = operands[3];
1550   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1551   rtx loop_label, end_label, mem, cr0, cond;
1552   if (search_char != const0_rtx
1553       || GET_CODE (align) != CONST_INT
1554       || INTVAL (align) < 8)
1555         FAIL;
1556   word1 = gen_reg_rtx (SImode);
1557   word2 = gen_reg_rtx (SImode);
1558   scratch_dlmzb = gen_reg_rtx (SImode);
1559   scratch_string = gen_reg_rtx (Pmode);
1560   loop_label = gen_label_rtx ();
1561   end_label = gen_label_rtx ();
1562   addr = force_reg (Pmode, XEXP (src, 0));
1563   emit_move_insn (scratch_string, addr);
1564   emit_label (loop_label);
1565   mem = change_address (src, SImode, scratch_string);
1566   emit_move_insn (word1, mem);
1567   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1568   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1569   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1570   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1571   emit_jump_insn (gen_rtx_SET (pc_rtx,
1572                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1573                                                      cond,
1574                                                      gen_rtx_LABEL_REF
1575                                                        (VOIDmode,
1576                                                         end_label),
1577                                                      pc_rtx)));
1578   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1579   emit_jump_insn (gen_rtx_SET (pc_rtx,
1580                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1581   emit_barrier ();
1582   emit_label (end_label);
1583   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1584   emit_insn (gen_subsi3 (result, scratch_string, addr));
1585   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1586   DONE;
1589 ;; Fixed-point arithmetic insns.
1591 (define_expand "add<mode>3"
1592   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1593         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1594                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1595   ""
1597   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1598     {
1599       rtx lo0 = gen_lowpart (SImode, operands[0]);
1600       rtx lo1 = gen_lowpart (SImode, operands[1]);
1601       rtx lo2 = gen_lowpart (SImode, operands[2]);
1602       rtx hi0 = gen_highpart (SImode, operands[0]);
1603       rtx hi1 = gen_highpart (SImode, operands[1]);
1604       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1606       if (!reg_or_short_operand (lo2, SImode))
1607         lo2 = force_reg (SImode, lo2);
1608       if (!adde_operand (hi2, SImode))
1609         hi2 = force_reg (SImode, hi2);
1611       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1612       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1613       DONE;
1614     }
1616   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1617     {
1618       rtx tmp = ((!can_create_pseudo_p ()
1619                   || rtx_equal_p (operands[0], operands[1]))
1620                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1622       HOST_WIDE_INT val = INTVAL (operands[2]);
1623       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1624       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1626       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1627         FAIL;
1629       /* The ordering here is important for the prolog expander.
1630          When space is allocated from the stack, adding 'low' first may
1631          produce a temporary deallocation (which would be bad).  */
1632       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1633       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1634       DONE;
1635     }
1638 (define_insn "*add<mode>3"
1639   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1640         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1641                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1642   ""
1643   "@
1644    add %0,%1,%2
1645    addi %0,%1,%2
1646    addis %0,%1,%v2"
1647   [(set_attr "type" "add")])
1649 (define_insn "addsi3_high"
1650   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1651         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1652                  (high:SI (match_operand 2 "" ""))))]
1653   "TARGET_MACHO && !TARGET_64BIT"
1654   "addis %0,%1,ha16(%2)"
1655   [(set_attr "type" "add")])
1657 (define_insn_and_split "*add<mode>3_dot"
1658   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1659         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1660                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1661                     (const_int 0)))
1662    (clobber (match_scratch:GPR 0 "=r,r"))]
1663   "<MODE>mode == Pmode"
1664   "@
1665    add. %0,%1,%2
1666    #"
1667   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1668   [(set (match_dup 0)
1669         (plus:GPR (match_dup 1)
1670                  (match_dup 2)))
1671    (set (match_dup 3)
1672         (compare:CC (match_dup 0)
1673                     (const_int 0)))]
1674   ""
1675   [(set_attr "type" "add")
1676    (set_attr "dot" "yes")
1677    (set_attr "length" "4,8")])
1679 (define_insn_and_split "*add<mode>3_dot2"
1680   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1681         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1682                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1683                     (const_int 0)))
1684    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1685         (plus:GPR (match_dup 1)
1686                   (match_dup 2)))]
1687   "<MODE>mode == Pmode"
1688   "@
1689    add. %0,%1,%2
1690    #"
1691   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1692   [(set (match_dup 0)
1693         (plus:GPR (match_dup 1)
1694                   (match_dup 2)))
1695    (set (match_dup 3)
1696         (compare:CC (match_dup 0)
1697                     (const_int 0)))]
1698   ""
1699   [(set_attr "type" "add")
1700    (set_attr "dot" "yes")
1701    (set_attr "length" "4,8")])
1703 (define_insn_and_split "*add<mode>3_imm_dot"
1704   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1705         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1706                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1707                     (const_int 0)))
1708    (clobber (match_scratch:GPR 0 "=r,r"))
1709    (clobber (reg:GPR CA_REGNO))]
1710   "<MODE>mode == Pmode"
1711   "@
1712    addic. %0,%1,%2
1713    #"
1714   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1715   [(set (match_dup 0)
1716         (plus:GPR (match_dup 1)
1717                   (match_dup 2)))
1718    (set (match_dup 3)
1719         (compare:CC (match_dup 0)
1720                     (const_int 0)))]
1721   ""
1722   [(set_attr "type" "add")
1723    (set_attr "dot" "yes")
1724    (set_attr "length" "4,8")])
1726 (define_insn_and_split "*add<mode>3_imm_dot2"
1727   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1728         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1729                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1730                     (const_int 0)))
1731    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1732         (plus:GPR (match_dup 1)
1733                   (match_dup 2)))
1734    (clobber (reg:GPR CA_REGNO))]
1735   "<MODE>mode == Pmode"
1736   "@
1737    addic. %0,%1,%2
1738    #"
1739   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1740   [(set (match_dup 0)
1741         (plus:GPR (match_dup 1)
1742                   (match_dup 2)))
1743    (set (match_dup 3)
1744         (compare:CC (match_dup 0)
1745                     (const_int 0)))]
1746   ""
1747   [(set_attr "type" "add")
1748    (set_attr "dot" "yes")
1749    (set_attr "length" "4,8")])
1751 ;; Split an add that we can't do in one insn into two insns, each of which
1752 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1753 ;; add should be last in case the result gets used in an address.
1755 (define_split
1756   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1757         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1758                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1759   ""
1760   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1761    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1763   HOST_WIDE_INT val = INTVAL (operands[2]);
1764   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1765   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1767   operands[4] = GEN_INT (low);
1768   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1769     operands[3] = GEN_INT (rest);
1770   else if (can_create_pseudo_p ())
1771     {
1772       operands[3] = gen_reg_rtx (DImode);
1773       emit_move_insn (operands[3], operands[2]);
1774       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1775       DONE;
1776     }
1777   else
1778     FAIL;
1782 (define_insn "add<mode>3_carry"
1783   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1784         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1785                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1786    (set (reg:P CA_REGNO)
1787         (ltu:P (plus:P (match_dup 1)
1788                        (match_dup 2))
1789                (match_dup 1)))]
1790   ""
1791   "add%I2c %0,%1,%2"
1792   [(set_attr "type" "add")])
1794 (define_insn "*add<mode>3_imm_carry_pos"
1795   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1796         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1797                 (match_operand:P 2 "short_cint_operand" "n")))
1798    (set (reg:P CA_REGNO)
1799         (geu:P (match_dup 1)
1800                (match_operand:P 3 "const_int_operand" "n")))]
1801   "INTVAL (operands[2]) > 0
1802    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1803   "addic %0,%1,%2"
1804   [(set_attr "type" "add")])
1806 (define_insn "*add<mode>3_imm_carry_0"
1807   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1808         (match_operand:P 1 "gpc_reg_operand" "r"))
1809    (set (reg:P CA_REGNO)
1810         (const_int 0))]
1811   ""
1812   "addic %0,%1,0"
1813   [(set_attr "type" "add")])
1815 (define_insn "*add<mode>3_imm_carry_m1"
1816   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1817         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1818                 (const_int -1)))
1819    (set (reg:P CA_REGNO)
1820         (ne:P (match_dup 1)
1821               (const_int 0)))]
1822   ""
1823   "addic %0,%1,-1"
1824   [(set_attr "type" "add")])
1826 (define_insn "*add<mode>3_imm_carry_neg"
1827   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1828         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1829                 (match_operand:P 2 "short_cint_operand" "n")))
1830    (set (reg:P CA_REGNO)
1831         (gtu:P (match_dup 1)
1832                (match_operand:P 3 "const_int_operand" "n")))]
1833   "INTVAL (operands[2]) < 0
1834    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1835   "addic %0,%1,%2"
1836   [(set_attr "type" "add")])
1839 (define_expand "add<mode>3_carry_in"
1840   [(parallel [
1841      (set (match_operand:GPR 0 "gpc_reg_operand")
1842           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1843                               (match_operand:GPR 2 "adde_operand"))
1844                     (reg:GPR CA_REGNO)))
1845      (clobber (reg:GPR CA_REGNO))])]
1846   ""
1848   if (operands[2] == const0_rtx)
1849     {
1850       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1851       DONE;
1852     }
1853   if (operands[2] == constm1_rtx)
1854     {
1855       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1856       DONE;
1857     }
1860 (define_insn "*add<mode>3_carry_in_internal"
1861   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1862         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1863                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1864                   (reg:GPR CA_REGNO)))
1865    (clobber (reg:GPR CA_REGNO))]
1866   ""
1867   "adde %0,%1,%2"
1868   [(set_attr "type" "add")])
1870 (define_insn "add<mode>3_carry_in_0"
1871   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1872         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1873                   (reg:GPR CA_REGNO)))
1874    (clobber (reg:GPR CA_REGNO))]
1875   ""
1876   "addze %0,%1"
1877   [(set_attr "type" "add")])
1879 (define_insn "add<mode>3_carry_in_m1"
1880   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1881         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1882                             (reg:GPR CA_REGNO))
1883                   (const_int -1)))
1884    (clobber (reg:GPR CA_REGNO))]
1885   ""
1886   "addme %0,%1"
1887   [(set_attr "type" "add")])
1890 (define_expand "one_cmpl<mode>2"
1891   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1892         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1893   ""
1895   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1896     {
1897       rs6000_split_logical (operands, NOT, false, false, false);
1898       DONE;
1899     }
1902 (define_insn "*one_cmpl<mode>2"
1903   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1904         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1905   ""
1906   "not %0,%1")
1908 (define_insn_and_split "*one_cmpl<mode>2_dot"
1909   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1910         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1911                     (const_int 0)))
1912    (clobber (match_scratch:GPR 0 "=r,r"))]
1913   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1914   "@
1915    not. %0,%1
1916    #"
1917   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1918   [(set (match_dup 0)
1919         (not:GPR (match_dup 1)))
1920    (set (match_dup 2)
1921         (compare:CC (match_dup 0)
1922                     (const_int 0)))]
1923   ""
1924   [(set_attr "type" "logical")
1925    (set_attr "dot" "yes")
1926    (set_attr "length" "4,8")])
1928 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1929   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1930         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1931                     (const_int 0)))
1932    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1933         (not:GPR (match_dup 1)))]
1934   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1935   "@
1936    not. %0,%1
1937    #"
1938   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1939   [(set (match_dup 0)
1940         (not:GPR (match_dup 1)))
1941    (set (match_dup 2)
1942         (compare:CC (match_dup 0)
1943                     (const_int 0)))]
1944   ""
1945   [(set_attr "type" "logical")
1946    (set_attr "dot" "yes")
1947    (set_attr "length" "4,8")])
1950 (define_expand "sub<mode>3"
1951   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1952         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1953                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1954   ""
1956   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1957     {
1958       rtx lo0 = gen_lowpart (SImode, operands[0]);
1959       rtx lo1 = gen_lowpart (SImode, operands[1]);
1960       rtx lo2 = gen_lowpart (SImode, operands[2]);
1961       rtx hi0 = gen_highpart (SImode, operands[0]);
1962       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1963       rtx hi2 = gen_highpart (SImode, operands[2]);
1965       if (!reg_or_short_operand (lo1, SImode))
1966         lo1 = force_reg (SImode, lo1);
1967       if (!adde_operand (hi1, SImode))
1968         hi1 = force_reg (SImode, hi1);
1970       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1971       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1972       DONE;
1973     }
1975   if (short_cint_operand (operands[1], <MODE>mode))
1976     {
1977       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1978       DONE;
1979     }
1982 (define_insn "*subf<mode>3"
1983   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1984         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1985                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1986   ""
1987   "subf %0,%1,%2"
1988   [(set_attr "type" "add")])
1990 (define_insn_and_split "*subf<mode>3_dot"
1991   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1992         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1993                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1994                     (const_int 0)))
1995    (clobber (match_scratch:GPR 0 "=r,r"))]
1996   "<MODE>mode == Pmode"
1997   "@
1998    subf. %0,%1,%2
1999    #"
2000   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2001   [(set (match_dup 0)
2002         (minus:GPR (match_dup 2)
2003                    (match_dup 1)))
2004    (set (match_dup 3)
2005         (compare:CC (match_dup 0)
2006                     (const_int 0)))]
2007   ""
2008   [(set_attr "type" "add")
2009    (set_attr "dot" "yes")
2010    (set_attr "length" "4,8")])
2012 (define_insn_and_split "*subf<mode>3_dot2"
2013   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2014         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2015                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2016                     (const_int 0)))
2017    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2018         (minus:GPR (match_dup 2)
2019                    (match_dup 1)))]
2020   "<MODE>mode == Pmode"
2021   "@
2022    subf. %0,%1,%2
2023    #"
2024   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2025   [(set (match_dup 0)
2026         (minus:GPR (match_dup 2)
2027                    (match_dup 1)))
2028    (set (match_dup 3)
2029         (compare:CC (match_dup 0)
2030                     (const_int 0)))]
2031   ""
2032   [(set_attr "type" "add")
2033    (set_attr "dot" "yes")
2034    (set_attr "length" "4,8")])
2036 (define_insn "subf<mode>3_imm"
2037   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2038         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2039                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2040    (clobber (reg:GPR CA_REGNO))]
2041   ""
2042   "subfic %0,%1,%2"
2043   [(set_attr "type" "add")])
2046 (define_insn "subf<mode>3_carry"
2047   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2048         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2049                  (match_operand:P 1 "gpc_reg_operand" "r")))
2050    (set (reg:P CA_REGNO)
2051         (leu:P (match_dup 1)
2052                (match_dup 2)))]
2053   ""
2054   "subf%I2c %0,%1,%2"
2055   [(set_attr "type" "add")])
2057 (define_insn "*subf<mode>3_imm_carry_0"
2058   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2059         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2060    (set (reg:P CA_REGNO)
2061         (eq:P (match_dup 1)
2062               (const_int 0)))]
2063   ""
2064   "subfic %0,%1,0"
2065   [(set_attr "type" "add")])
2067 (define_insn "*subf<mode>3_imm_carry_m1"
2068   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2069         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2070    (set (reg:P CA_REGNO)
2071         (const_int 1))]
2072   ""
2073   "subfic %0,%1,-1"
2074   [(set_attr "type" "add")])
2077 (define_expand "subf<mode>3_carry_in"
2078   [(parallel [
2079      (set (match_operand:GPR 0 "gpc_reg_operand")
2080           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2081                               (reg:GPR CA_REGNO))
2082                     (match_operand:GPR 2 "adde_operand")))
2083      (clobber (reg:GPR CA_REGNO))])]
2084   ""
2086   if (operands[2] == const0_rtx)
2087     {
2088       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2089       DONE;
2090     }
2091   if (operands[2] == constm1_rtx)
2092     {
2093       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2094       DONE;
2095     }
2098 (define_insn "*subf<mode>3_carry_in_internal"
2099   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2100         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2101                             (reg:GPR CA_REGNO))
2102                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2103    (clobber (reg:GPR CA_REGNO))]
2104   ""
2105   "subfe %0,%1,%2"
2106   [(set_attr "type" "add")])
2108 (define_insn "subf<mode>3_carry_in_0"
2109   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2110         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2111                   (reg:GPR CA_REGNO)))
2112    (clobber (reg:GPR CA_REGNO))]
2113   ""
2114   "subfze %0,%1"
2115   [(set_attr "type" "add")])
2117 (define_insn "subf<mode>3_carry_in_m1"
2118   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2119         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2120                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2121                   (const_int -2)))
2122    (clobber (reg:GPR CA_REGNO))]
2123   ""
2124   "subfme %0,%1"
2125   [(set_attr "type" "add")])
2127 (define_insn "subf<mode>3_carry_in_xx"
2128   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2129         (plus:GPR (reg:GPR CA_REGNO)
2130                   (const_int -1)))
2131    (clobber (reg:GPR CA_REGNO))]
2132   ""
2133   "subfe %0,%0,%0"
2134   [(set_attr "type" "add")])
2137 (define_insn "neg<mode>2"
2138   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2139         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2140   ""
2141   "neg %0,%1"
2142   [(set_attr "type" "add")])
2144 (define_insn_and_split "*neg<mode>2_dot"
2145   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2146         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2147                     (const_int 0)))
2148    (clobber (match_scratch:GPR 0 "=r,r"))]
2149   "<MODE>mode == Pmode"
2150   "@
2151    neg. %0,%1
2152    #"
2153   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2154   [(set (match_dup 0)
2155         (neg:GPR (match_dup 1)))
2156    (set (match_dup 2)
2157         (compare:CC (match_dup 0)
2158                     (const_int 0)))]
2159   ""
2160   [(set_attr "type" "add")
2161    (set_attr "dot" "yes")
2162    (set_attr "length" "4,8")])
2164 (define_insn_and_split "*neg<mode>2_dot2"
2165   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2166         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2167                     (const_int 0)))
2168    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2169         (neg:GPR (match_dup 1)))]
2170   "<MODE>mode == Pmode"
2171   "@
2172    neg. %0,%1
2173    #"
2174   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2175   [(set (match_dup 0)
2176         (neg:GPR (match_dup 1)))
2177    (set (match_dup 2)
2178         (compare:CC (match_dup 0)
2179                     (const_int 0)))]
2180   ""
2181   [(set_attr "type" "add")
2182    (set_attr "dot" "yes")
2183    (set_attr "length" "4,8")])
2186 (define_insn "clz<mode>2"
2187   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2188         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2189   ""
2190   "cntlz<wd> %0,%1"
2191   [(set_attr "type" "cntlz")])
2193 (define_expand "ctz<mode>2"
2194   [(set (match_dup 2)
2195         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2196    (set (match_dup 3)
2197         (and:GPR (match_dup 1)
2198                  (match_dup 2)))
2199    (set (match_dup 4)
2200         (clz:GPR (match_dup 3)))
2201    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2202                    (minus:GPR (match_dup 5)
2203                               (match_dup 4)))
2204               (clobber (reg:GPR CA_REGNO))])]
2205   ""
2207   if (TARGET_CTZ)
2208     {
2209       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2210       DONE;
2211     }
2213   operands[2] = gen_reg_rtx (<MODE>mode);
2214   operands[3] = gen_reg_rtx (<MODE>mode);
2215   operands[4] = gen_reg_rtx (<MODE>mode);
2216   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2219 (define_insn "ctz<mode>2_hw"
2220   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2221         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2222   "TARGET_CTZ"
2223   "cnttz<wd> %0,%1"
2224   [(set_attr "type" "cntlz")])
2226 (define_expand "ffs<mode>2"
2227   [(set (match_dup 2)
2228         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2229    (set (match_dup 3)
2230         (and:GPR (match_dup 1)
2231                  (match_dup 2)))
2232    (set (match_dup 4)
2233         (clz:GPR (match_dup 3)))
2234    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2235                    (minus:GPR (match_dup 5)
2236                               (match_dup 4)))
2237               (clobber (reg:GPR CA_REGNO))])]
2238   ""
2240   operands[2] = gen_reg_rtx (<MODE>mode);
2241   operands[3] = gen_reg_rtx (<MODE>mode);
2242   operands[4] = gen_reg_rtx (<MODE>mode);
2243   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2247 (define_expand "popcount<mode>2"
2248   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2249         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2250   "TARGET_POPCNTB || TARGET_POPCNTD"
2252   rs6000_emit_popcount (operands[0], operands[1]);
2253   DONE;
2256 (define_insn "popcntb<mode>2"
2257   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2258         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2259                     UNSPEC_POPCNTB))]
2260   "TARGET_POPCNTB"
2261   "popcntb %0,%1"
2262   [(set_attr "type" "popcnt")])
2264 (define_insn "popcntd<mode>2"
2265   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2266         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2267   "TARGET_POPCNTD"
2268   "popcnt<wd> %0,%1"
2269   [(set_attr "type" "popcnt")])
2272 (define_expand "parity<mode>2"
2273   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2274         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2275   "TARGET_POPCNTB"
2277   rs6000_emit_parity (operands[0], operands[1]);
2278   DONE;
2281 (define_insn "parity<mode>2_cmpb"
2282   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2283         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2284   "TARGET_CMPB && TARGET_POPCNTB"
2285   "prty<wd> %0,%1"
2286   [(set_attr "type" "popcnt")])
2289 ;; Since the hardware zeros the upper part of the register, save generating the
2290 ;; AND immediate if we are converting to unsigned
2291 (define_insn "*bswaphi2_extenddi"
2292   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2293         (zero_extend:DI
2294          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2295   "TARGET_POWERPC64"
2296   "lhbrx %0,%y1"
2297   [(set_attr "length" "4")
2298    (set_attr "type" "load")])
2300 (define_insn "*bswaphi2_extendsi"
2301   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2302         (zero_extend:SI
2303          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2304   ""
2305   "lhbrx %0,%y1"
2306   [(set_attr "length" "4")
2307    (set_attr "type" "load")])
2309 (define_expand "bswaphi2"
2310   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2311                    (bswap:HI
2312                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2313               (clobber (match_scratch:SI 2 ""))])]
2314   ""
2316   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2317     operands[1] = force_reg (HImode, operands[1]);
2320 (define_insn "bswaphi2_internal"
2321   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2322         (bswap:HI
2323          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2324    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2325   ""
2326   "@
2327    lhbrx %0,%y1
2328    sthbrx %1,%y0
2329    #"
2330   [(set_attr "length" "4,4,12")
2331    (set_attr "type" "load,store,*")])
2333 (define_split
2334   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2335         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2336    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2337   "reload_completed"
2338   [(set (match_dup 3)
2339         (and:SI (lshiftrt:SI (match_dup 4)
2340                              (const_int 8))
2341                 (const_int 255)))
2342    (set (match_dup 2)
2343         (and:SI (ashift:SI (match_dup 4)
2344                            (const_int 8))
2345                 (const_int 65280)))             ;; 0xff00
2346    (set (match_dup 3)
2347         (ior:SI (match_dup 3)
2348                 (match_dup 2)))]
2349   "
2351   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2352   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2355 (define_insn "*bswapsi2_extenddi"
2356   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2357         (zero_extend:DI
2358          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2359   "TARGET_POWERPC64"
2360   "lwbrx %0,%y1"
2361   [(set_attr "length" "4")
2362    (set_attr "type" "load")])
2364 (define_expand "bswapsi2"
2365   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2366         (bswap:SI
2367          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2368   ""
2370   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2371     operands[1] = force_reg (SImode, operands[1]);
2374 (define_insn "*bswapsi2_internal"
2375   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2376         (bswap:SI
2377          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2378   ""
2379   "@
2380    lwbrx %0,%y1
2381    stwbrx %1,%y0
2382    #"
2383   [(set_attr "length" "4,4,12")
2384    (set_attr "type" "load,store,*")])
2386 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2387 ;; zero_extract insns do not change for -mlittle.
2388 (define_split
2389   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2390         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2391   "reload_completed"
2392   [(set (match_dup 0)                                   ; DABC
2393         (rotate:SI (match_dup 1)
2394                    (const_int 24)))
2395    (set (match_dup 0)                                   ; DCBC
2396         (ior:SI (and:SI (ashift:SI (match_dup 1)
2397                                    (const_int 8))
2398                         (const_int 16711680))
2399                 (and:SI (match_dup 0)
2400                         (const_int -16711681))))
2401    (set (match_dup 0)                                   ; DCBA
2402         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2403                                      (const_int 24))
2404                         (const_int 255))
2405                 (and:SI (match_dup 0)
2406                         (const_int -256))))
2408   ]
2409   "")
2411 (define_expand "bswapdi2"
2412   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2413                    (bswap:DI
2414                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2415               (clobber (match_scratch:DI 2 ""))
2416               (clobber (match_scratch:DI 3 ""))])]
2417   ""
2419   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2420     operands[1] = force_reg (DImode, operands[1]);
2422   if (!TARGET_POWERPC64)
2423     {
2424       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2425          that uses 64-bit registers needs the same scratch registers as 64-bit
2426          mode.  */
2427       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2428       DONE;
2429     }
2432 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2433 (define_insn "*bswapdi2_ldbrx"
2434   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2435         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2436    (clobber (match_scratch:DI 2 "=X,X,&r"))
2437    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2438   "TARGET_POWERPC64 && TARGET_LDBRX
2439    && (REG_P (operands[0]) || REG_P (operands[1]))"
2440   "@
2441    ldbrx %0,%y1
2442    stdbrx %1,%y0
2443    #"
2444   [(set_attr "length" "4,4,36")
2445    (set_attr "type" "load,store,*")])
2447 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2448 (define_insn "*bswapdi2_64bit"
2449   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2450         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2451    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2452    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2453   "TARGET_POWERPC64 && !TARGET_LDBRX
2454    && (REG_P (operands[0]) || REG_P (operands[1]))
2455    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2456    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2457   "#"
2458   [(set_attr "length" "16,12,36")])
2460 (define_split
2461   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2462         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2463    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2464    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2465   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2466   [(const_int 0)]
2467   "
2469   rtx dest   = operands[0];
2470   rtx src    = operands[1];
2471   rtx op2    = operands[2];
2472   rtx op3    = operands[3];
2473   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2474                                     BYTES_BIG_ENDIAN ? 4 : 0);
2475   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2476                                      BYTES_BIG_ENDIAN ? 4 : 0);
2477   rtx addr1;
2478   rtx addr2;
2479   rtx word1;
2480   rtx word2;
2482   addr1 = XEXP (src, 0);
2483   if (GET_CODE (addr1) == PLUS)
2484     {
2485       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2486       if (TARGET_AVOID_XFORM)
2487         {
2488           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2489           addr2 = op2;
2490         }
2491       else
2492         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2493     }
2494   else if (TARGET_AVOID_XFORM)
2495     {
2496       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2497       addr2 = op2;
2498     }
2499   else
2500     {
2501       emit_move_insn (op2, GEN_INT (4));
2502       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2503     }
2505   word1 = change_address (src, SImode, addr1);
2506   word2 = change_address (src, SImode, addr2);
2508   if (BYTES_BIG_ENDIAN)
2509     {
2510       emit_insn (gen_bswapsi2 (op3_32, word2));
2511       emit_insn (gen_bswapsi2 (dest_32, word1));
2512     }
2513   else
2514     {
2515       emit_insn (gen_bswapsi2 (op3_32, word1));
2516       emit_insn (gen_bswapsi2 (dest_32, word2));
2517     }
2519   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2520   emit_insn (gen_iordi3 (dest, dest, op3));
2521   DONE;
2524 (define_split
2525   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2526         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2527    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2528    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2529   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2530   [(const_int 0)]
2531   "
2533   rtx dest   = operands[0];
2534   rtx src    = operands[1];
2535   rtx op2    = operands[2];
2536   rtx op3    = operands[3];
2537   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2538                                     BYTES_BIG_ENDIAN ? 4 : 0);
2539   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2540                                     BYTES_BIG_ENDIAN ? 4 : 0);
2541   rtx addr1;
2542   rtx addr2;
2543   rtx word1;
2544   rtx word2;
2546   addr1 = XEXP (dest, 0);
2547   if (GET_CODE (addr1) == PLUS)
2548     {
2549       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2550       if (TARGET_AVOID_XFORM)
2551         {
2552           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2553           addr2 = op2;
2554         }
2555       else
2556         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2557     }
2558   else if (TARGET_AVOID_XFORM)
2559     {
2560       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2561       addr2 = op2;
2562     }
2563   else
2564     {
2565       emit_move_insn (op2, GEN_INT (4));
2566       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2567     }
2569   word1 = change_address (dest, SImode, addr1);
2570   word2 = change_address (dest, SImode, addr2);
2572   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2574   if (BYTES_BIG_ENDIAN)
2575     {
2576       emit_insn (gen_bswapsi2 (word1, src_si));
2577       emit_insn (gen_bswapsi2 (word2, op3_si));
2578     }
2579   else
2580     {
2581       emit_insn (gen_bswapsi2 (word2, src_si));
2582       emit_insn (gen_bswapsi2 (word1, op3_si));
2583     }
2584   DONE;
2587 (define_split
2588   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2589         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2590    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2591    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2592   "TARGET_POWERPC64 && reload_completed"
2593   [(const_int 0)]
2594   "
2596   rtx dest    = operands[0];
2597   rtx src     = operands[1];
2598   rtx op2     = operands[2];
2599   rtx op3     = operands[3];
2600   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2601   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2602   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2603   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2604   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2606   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2607   emit_insn (gen_bswapsi2 (dest_si, src_si));
2608   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2609   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2610   emit_insn (gen_iordi3 (dest, dest, op3));
2611   DONE;
2614 (define_insn "bswapdi2_32bit"
2615   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2616         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2617    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2618   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2619   "#"
2620   [(set_attr "length" "16,12,36")])
2622 (define_split
2623   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2624         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2625    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2626   "!TARGET_POWERPC64 && reload_completed"
2627   [(const_int 0)]
2628   "
2630   rtx dest  = operands[0];
2631   rtx src   = operands[1];
2632   rtx op2   = operands[2];
2633   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2634   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2635   rtx addr1;
2636   rtx addr2;
2637   rtx word1;
2638   rtx word2;
2640   addr1 = XEXP (src, 0);
2641   if (GET_CODE (addr1) == PLUS)
2642     {
2643       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2644       if (TARGET_AVOID_XFORM
2645           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2646         {
2647           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2648           addr2 = op2;
2649         }
2650       else
2651         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2652     }
2653   else if (TARGET_AVOID_XFORM
2654            || REGNO (addr1) == REGNO (dest2))
2655     {
2656       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2657       addr2 = op2;
2658     }
2659   else
2660     {
2661       emit_move_insn (op2, GEN_INT (4));
2662       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2663     }
2665   word1 = change_address (src, SImode, addr1);
2666   word2 = change_address (src, SImode, addr2);
2668   emit_insn (gen_bswapsi2 (dest2, word1));
2669   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2670      thus allowing us to omit an early clobber on the output.  */
2671   emit_insn (gen_bswapsi2 (dest1, word2));
2672   DONE;
2675 (define_split
2676   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2677         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2678    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2679   "!TARGET_POWERPC64 && reload_completed"
2680   [(const_int 0)]
2681   "
2683   rtx dest = operands[0];
2684   rtx src  = operands[1];
2685   rtx op2  = operands[2];
2686   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2687   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2688   rtx addr1;
2689   rtx addr2;
2690   rtx word1;
2691   rtx word2;
2693   addr1 = XEXP (dest, 0);
2694   if (GET_CODE (addr1) == PLUS)
2695     {
2696       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2697       if (TARGET_AVOID_XFORM)
2698         {
2699           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2700           addr2 = op2;
2701         }
2702       else
2703         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2704     }
2705   else if (TARGET_AVOID_XFORM)
2706     {
2707       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2708       addr2 = op2;
2709     }
2710   else
2711     {
2712       emit_move_insn (op2, GEN_INT (4));
2713       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2714     }
2716   word1 = change_address (dest, SImode, addr1);
2717   word2 = change_address (dest, SImode, addr2);
2719   emit_insn (gen_bswapsi2 (word2, src1));
2720   emit_insn (gen_bswapsi2 (word1, src2));
2721   DONE;
2724 (define_split
2725   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2726         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2727    (clobber (match_operand:SI 2 "" ""))]
2728   "!TARGET_POWERPC64 && reload_completed"
2729   [(const_int 0)]
2730   "
2732   rtx dest  = operands[0];
2733   rtx src   = operands[1];
2734   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2735   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2736   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2737   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2739   emit_insn (gen_bswapsi2 (dest1, src2));
2740   emit_insn (gen_bswapsi2 (dest2, src1));
2741   DONE;
2745 (define_insn "mul<mode>3"
2746   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2747         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2748                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2749   ""
2750   "@
2751    mull<wd> %0,%1,%2
2752    mulli %0,%1,%2"
2753    [(set_attr "type" "mul")
2754     (set (attr "size")
2755       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2756                 (const_string "8")
2757              (match_operand:GPR 2 "short_cint_operand" "")
2758                 (const_string "16")]
2759         (const_string "<bits>")))])
2761 (define_insn_and_split "*mul<mode>3_dot"
2762   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2763         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2764                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2765                     (const_int 0)))
2766    (clobber (match_scratch:GPR 0 "=r,r"))]
2767   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2768   "@
2769    mull<wd>. %0,%1,%2
2770    #"
2771   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2772   [(set (match_dup 0)
2773         (mult:GPR (match_dup 1)
2774                   (match_dup 2)))
2775    (set (match_dup 3)
2776         (compare:CC (match_dup 0)
2777                     (const_int 0)))]
2778   ""
2779   [(set_attr "type" "mul")
2780    (set_attr "size" "<bits>")
2781    (set_attr "dot" "yes")
2782    (set_attr "length" "4,8")])
2784 (define_insn_and_split "*mul<mode>3_dot2"
2785   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2786         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2787                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2788                     (const_int 0)))
2789    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2790         (mult:GPR (match_dup 1)
2791                   (match_dup 2)))]
2792   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2793   "@
2794    mull<wd>. %0,%1,%2
2795    #"
2796   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2797   [(set (match_dup 0)
2798         (mult:GPR (match_dup 1)
2799                   (match_dup 2)))
2800    (set (match_dup 3)
2801         (compare:CC (match_dup 0)
2802                     (const_int 0)))]
2803   ""
2804   [(set_attr "type" "mul")
2805    (set_attr "size" "<bits>")
2806    (set_attr "dot" "yes")
2807    (set_attr "length" "4,8")])
2810 (define_expand "<su>mul<mode>3_highpart"
2811   [(set (match_operand:GPR 0 "gpc_reg_operand")
2812         (subreg:GPR
2813           (mult:<DMODE> (any_extend:<DMODE>
2814                           (match_operand:GPR 1 "gpc_reg_operand"))
2815                         (any_extend:<DMODE>
2816                           (match_operand:GPR 2 "gpc_reg_operand")))
2817          0))]
2818   ""
2820   if (<MODE>mode == SImode && TARGET_POWERPC64)
2821     {
2822       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2823                                              operands[2]));
2824       DONE;
2825     }
2827   if (!WORDS_BIG_ENDIAN)
2828     {
2829       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2830                                                  operands[2]));
2831       DONE;
2832     }
2835 (define_insn "*<su>mul<mode>3_highpart"
2836   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2837         (subreg:GPR
2838           (mult:<DMODE> (any_extend:<DMODE>
2839                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2840                         (any_extend:<DMODE>
2841                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2842          0))]
2843   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2844   "mulh<wd><u> %0,%1,%2"
2845   [(set_attr "type" "mul")
2846    (set_attr "size" "<bits>")])
2848 (define_insn "<su>mulsi3_highpart_le"
2849   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2850         (subreg:SI
2851           (mult:DI (any_extend:DI
2852                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2853                    (any_extend:DI
2854                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2855          4))]
2856   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2857   "mulhw<u> %0,%1,%2"
2858   [(set_attr "type" "mul")])
2860 (define_insn "<su>muldi3_highpart_le"
2861   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2862         (subreg:DI
2863           (mult:TI (any_extend:TI
2864                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2865                    (any_extend:TI
2866                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2867          8))]
2868   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2869   "mulhd<u> %0,%1,%2"
2870   [(set_attr "type" "mul")
2871    (set_attr "size" "64")])
2873 (define_insn "<su>mulsi3_highpart_64"
2874   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2875         (truncate:SI
2876           (lshiftrt:DI
2877             (mult:DI (any_extend:DI
2878                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2879                      (any_extend:DI
2880                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2881             (const_int 32))))]
2882   "TARGET_POWERPC64"
2883   "mulhw<u> %0,%1,%2"
2884   [(set_attr "type" "mul")])
2886 (define_expand "<u>mul<mode><dmode>3"
2887   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2888         (mult:<DMODE> (any_extend:<DMODE>
2889                         (match_operand:GPR 1 "gpc_reg_operand"))
2890                       (any_extend:<DMODE>
2891                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2892   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2894   rtx l = gen_reg_rtx (<MODE>mode);
2895   rtx h = gen_reg_rtx (<MODE>mode);
2896   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2897   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2898   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2899   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2900   DONE;
2903 (define_insn "*maddld4"
2904   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2905         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2906                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2907                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2908   "TARGET_MADDLD"
2909   "maddld %0,%1,%2,%3"
2910   [(set_attr "type" "mul")])
2912 (define_insn "udiv<mode>3"
2913   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2914         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2915                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2916   ""
2917   "div<wd>u %0,%1,%2"
2918   [(set_attr "type" "div")
2919    (set_attr "size" "<bits>")])
2922 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2923 ;; modulus.  If it isn't a power of two, force operands into register and do
2924 ;; a normal divide.
2925 (define_expand "div<mode>3"
2926   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2927         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2928                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2929   ""
2931   if (CONST_INT_P (operands[2])
2932       && INTVAL (operands[2]) > 0
2933       && exact_log2 (INTVAL (operands[2])) >= 0)
2934     {
2935       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2936       DONE;
2937     }
2939   operands[2] = force_reg (<MODE>mode, operands[2]);
2942 (define_insn "*div<mode>3"
2943   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2944         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2945                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2946   ""
2947   "div<wd> %0,%1,%2"
2948   [(set_attr "type" "div")
2949    (set_attr "size" "<bits>")])
2951 (define_insn "div<mode>3_sra"
2952   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2953         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2954                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2955    (clobber (reg:GPR CA_REGNO))]
2956   ""
2957   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2958   [(set_attr "type" "two")
2959    (set_attr "length" "8")])
2961 (define_insn_and_split "*div<mode>3_sra_dot"
2962   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2963         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2964                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2965                     (const_int 0)))
2966    (clobber (match_scratch:GPR 0 "=r,r"))
2967    (clobber (reg:GPR CA_REGNO))]
2968   "<MODE>mode == Pmode"
2969   "@
2970    sra<wd>i %0,%1,%p2\;addze. %0,%0
2971    #"
2972   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2973   [(parallel [(set (match_dup 0)
2974                    (div:GPR (match_dup 1)
2975                             (match_dup 2)))
2976               (clobber (reg:GPR CA_REGNO))])
2977    (set (match_dup 3)
2978         (compare:CC (match_dup 0)
2979                     (const_int 0)))]
2980   ""
2981   [(set_attr "type" "two")
2982    (set_attr "length" "8,12")
2983    (set_attr "cell_micro" "not")])
2985 (define_insn_and_split "*div<mode>3_sra_dot2"
2986   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2987         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2988                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2989                     (const_int 0)))
2990    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2991         (div:GPR (match_dup 1)
2992                  (match_dup 2)))
2993    (clobber (reg:GPR CA_REGNO))]
2994   "<MODE>mode == Pmode"
2995   "@
2996    sra<wd>i %0,%1,%p2\;addze. %0,%0
2997    #"
2998   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2999   [(parallel [(set (match_dup 0)
3000                    (div:GPR (match_dup 1)
3001                             (match_dup 2)))
3002               (clobber (reg:GPR CA_REGNO))])
3003    (set (match_dup 3)
3004         (compare:CC (match_dup 0)
3005                     (const_int 0)))]
3006   ""
3007   [(set_attr "type" "two")
3008    (set_attr "length" "8,12")
3009    (set_attr "cell_micro" "not")])
3011 (define_expand "mod<mode>3"
3012   [(set (match_operand:GPR 0 "gpc_reg_operand")
3013         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3014                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3015   ""
3017   int i;
3018   rtx temp1;
3019   rtx temp2;
3021   if (GET_CODE (operands[2]) != CONST_INT
3022       || INTVAL (operands[2]) <= 0
3023       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3024     {
3025       if (!TARGET_MODULO)
3026         FAIL;
3028       operands[2] = force_reg (<MODE>mode, operands[2]);
3029     }
3030   else
3031     {
3032       temp1 = gen_reg_rtx (<MODE>mode);
3033       temp2 = gen_reg_rtx (<MODE>mode);
3035       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3036       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3037       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3038       DONE;
3039     }
3042 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3043 ;; mod, prefer putting the result of mod into a different register
3044 (define_insn "*mod<mode>3"
3045   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3046         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3047                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3048   "TARGET_MODULO"
3049   "mods<wd> %0,%1,%2"
3050   [(set_attr "type" "div")
3051    (set_attr "size" "<bits>")])
3054 (define_insn "umod<mode>3"
3055   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3056         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3057                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3058   "TARGET_MODULO"
3059   "modu<wd> %0,%1,%2"
3060   [(set_attr "type" "div")
3061    (set_attr "size" "<bits>")])
3063 ;; On machines with modulo support, do a combined div/mod the old fashioned
3064 ;; method, since the multiply/subtract is faster than doing the mod instruction
3065 ;; after a divide.
3067 (define_peephole2
3068   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3069         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3070                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3071    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3072         (mod:GPR (match_dup 1)
3073                  (match_dup 2)))]
3074   "TARGET_MODULO
3075    && ! reg_mentioned_p (operands[0], operands[1])
3076    && ! reg_mentioned_p (operands[0], operands[2])
3077    && ! reg_mentioned_p (operands[3], operands[1])
3078    && ! reg_mentioned_p (operands[3], operands[2])"
3079   [(set (match_dup 0)
3080         (div:GPR (match_dup 1)
3081                  (match_dup 2)))
3082    (set (match_dup 3)
3083         (mult:GPR (match_dup 0)
3084                   (match_dup 2)))
3085    (set (match_dup 3)
3086         (minus:GPR (match_dup 1)
3087                    (match_dup 3)))])
3089 (define_peephole2
3090   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3091         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3092                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3093    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3094         (umod:GPR (match_dup 1)
3095                   (match_dup 2)))]
3096   "TARGET_MODULO
3097    && ! reg_mentioned_p (operands[0], operands[1])
3098    && ! reg_mentioned_p (operands[0], operands[2])
3099    && ! reg_mentioned_p (operands[3], operands[1])
3100    && ! reg_mentioned_p (operands[3], operands[2])"
3101   [(set (match_dup 0)
3102         (div:GPR (match_dup 1)
3103                  (match_dup 2)))
3104    (set (match_dup 3)
3105         (mult:GPR (match_dup 0)
3106                   (match_dup 2)))
3107    (set (match_dup 3)
3108         (minus:GPR (match_dup 1)
3109                    (match_dup 3)))])
3112 ;; Logical instructions
3113 ;; The logical instructions are mostly combined by using match_operator,
3114 ;; but the plain AND insns are somewhat different because there is no
3115 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3116 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3118 (define_expand "and<mode>3"
3119   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3120         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3121                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3122   ""
3124   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3125     {
3126       rs6000_split_logical (operands, AND, false, false, false);
3127       DONE;
3128     }
3130   if (CONST_INT_P (operands[2]))
3131     {
3132       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3133         {
3134           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3135           DONE;
3136         }
3138       if (logical_const_operand (operands[2], <MODE>mode)
3139           && rs6000_gen_cell_microcode)
3140         {
3141           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3142           DONE;
3143         }
3145       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3146         {
3147           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3148           DONE;
3149         }
3151       operands[2] = force_reg (<MODE>mode, operands[2]);
3152     }
3156 (define_insn "and<mode>3_imm"
3157   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3158         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3159                  (match_operand:GPR 2 "logical_const_operand" "n")))
3160    (clobber (match_scratch:CC 3 "=x"))]
3161   "rs6000_gen_cell_microcode
3162    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3163   "andi%e2. %0,%1,%u2"
3164   [(set_attr "type" "logical")
3165    (set_attr "dot" "yes")])
3167 (define_insn_and_split "*and<mode>3_imm_dot"
3168   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3169         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3170                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3171                     (const_int 0)))
3172    (clobber (match_scratch:GPR 0 "=r,r"))
3173    (clobber (match_scratch:CC 4 "=X,x"))]
3174   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3175    && rs6000_gen_cell_microcode
3176    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3177   "@
3178    andi%e2. %0,%1,%u2
3179    #"
3180   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3181   [(parallel [(set (match_dup 0)
3182                    (and:GPR (match_dup 1)
3183                             (match_dup 2)))
3184               (clobber (match_dup 4))])
3185    (set (match_dup 3)
3186         (compare:CC (match_dup 0)
3187                     (const_int 0)))]
3188   ""
3189   [(set_attr "type" "logical")
3190    (set_attr "dot" "yes")
3191    (set_attr "length" "4,8")])
3193 (define_insn_and_split "*and<mode>3_imm_dot2"
3194   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3195         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3196                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3197                     (const_int 0)))
3198    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3199         (and:GPR (match_dup 1)
3200                  (match_dup 2)))
3201    (clobber (match_scratch:CC 4 "=X,x"))]
3202   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3203    && rs6000_gen_cell_microcode
3204    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3205   "@
3206    andi%e2. %0,%1,%u2
3207    #"
3208   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3209   [(parallel [(set (match_dup 0)
3210                    (and:GPR (match_dup 1)
3211                             (match_dup 2)))
3212               (clobber (match_dup 4))])
3213    (set (match_dup 3)
3214         (compare:CC (match_dup 0)
3215                     (const_int 0)))]
3216   ""
3217   [(set_attr "type" "logical")
3218    (set_attr "dot" "yes")
3219    (set_attr "length" "4,8")])
3221 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3222   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3223         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3224                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3225                     (const_int 0)))
3226    (clobber (match_scratch:GPR 0 "=r,r"))]
3227   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3228    && rs6000_gen_cell_microcode"
3229   "@
3230    andi%e2. %0,%1,%u2
3231    #"
3232   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3233   [(set (match_dup 0)
3234         (and:GPR (match_dup 1)
3235                  (match_dup 2)))
3236    (set (match_dup 3)
3237         (compare:CC (match_dup 0)
3238                     (const_int 0)))]
3239   ""
3240   [(set_attr "type" "logical")
3241    (set_attr "dot" "yes")
3242    (set_attr "length" "4,8")])
3244 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3245   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3246         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3247                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3248                     (const_int 0)))
3249    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3250         (and:GPR (match_dup 1)
3251                  (match_dup 2)))]
3252   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3253    && rs6000_gen_cell_microcode"
3254   "@
3255    andi%e2. %0,%1,%u2
3256    #"
3257   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3258   [(set (match_dup 0)
3259         (and:GPR (match_dup 1)
3260                  (match_dup 2)))
3261    (set (match_dup 3)
3262         (compare:CC (match_dup 0)
3263                     (const_int 0)))]
3264   ""
3265   [(set_attr "type" "logical")
3266    (set_attr "dot" "yes")
3267    (set_attr "length" "4,8")])
3269 (define_insn "*and<mode>3_imm_dot_shifted"
3270   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3271         (compare:CC
3272           (and:GPR
3273             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3274                           (match_operand:SI 4 "const_int_operand" "n"))
3275             (match_operand:GPR 2 "const_int_operand" "n"))
3276           (const_int 0)))
3277    (clobber (match_scratch:GPR 0 "=r"))]
3278   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3279                                    << INTVAL (operands[4])),
3280                           DImode)
3281    && (<MODE>mode == Pmode
3282        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3283    && rs6000_gen_cell_microcode"
3285   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3286   return "andi%e2. %0,%1,%u2";
3288   [(set_attr "type" "logical")
3289    (set_attr "dot" "yes")])
3292 (define_insn "and<mode>3_mask"
3293   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3294         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3295                  (match_operand:GPR 2 "const_int_operand" "n")))]
3296   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3298   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3300   [(set_attr "type" "shift")])
3302 (define_insn_and_split "*and<mode>3_mask_dot"
3303   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3304         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3305                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3306                     (const_int 0)))
3307    (clobber (match_scratch:GPR 0 "=r,r"))]
3308   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3309    && rs6000_gen_cell_microcode
3310    && !logical_const_operand (operands[2], <MODE>mode)
3311    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3313   if (which_alternative == 0)
3314     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3315   else
3316     return "#";
3318   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319   [(set (match_dup 0)
3320         (and:GPR (match_dup 1)
3321                  (match_dup 2)))
3322    (set (match_dup 3)
3323         (compare:CC (match_dup 0)
3324                     (const_int 0)))]
3325   ""
3326   [(set_attr "type" "shift")
3327    (set_attr "dot" "yes")
3328    (set_attr "length" "4,8")])
3330 (define_insn_and_split "*and<mode>3_mask_dot2"
3331   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3332         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3333                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3334                     (const_int 0)))
3335    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3336         (and:GPR (match_dup 1)
3337                  (match_dup 2)))]
3338   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3339    && rs6000_gen_cell_microcode
3340    && !logical_const_operand (operands[2], <MODE>mode)
3341    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3343   if (which_alternative == 0)
3344     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3345   else
3346     return "#";
3348   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3349   [(set (match_dup 0)
3350         (and:GPR (match_dup 1)
3351                  (match_dup 2)))
3352    (set (match_dup 3)
3353         (compare:CC (match_dup 0)
3354                     (const_int 0)))]
3355   ""
3356   [(set_attr "type" "shift")
3357    (set_attr "dot" "yes")
3358    (set_attr "length" "4,8")])
3361 (define_insn_and_split "*and<mode>3_2insn"
3362   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3363         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3364                  (match_operand:GPR 2 "const_int_operand" "n")))]
3365   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3366    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3367         || (logical_const_operand (operands[2], <MODE>mode)
3368             && rs6000_gen_cell_microcode))"
3369   "#"
3370   "&& 1"
3371   [(pc)]
3373   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3374   DONE;
3376   [(set_attr "type" "shift")
3377    (set_attr "length" "8")])
3379 (define_insn_and_split "*and<mode>3_2insn_dot"
3380   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3381         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3382                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3383                     (const_int 0)))
3384    (clobber (match_scratch:GPR 0 "=r,r"))]
3385   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3386    && rs6000_gen_cell_microcode
3387    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3388    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3389         || (logical_const_operand (operands[2], <MODE>mode)
3390             && rs6000_gen_cell_microcode))"
3391   "#"
3392   "&& reload_completed"
3393   [(pc)]
3395   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3396   DONE;
3398   [(set_attr "type" "shift")
3399    (set_attr "dot" "yes")
3400    (set_attr "length" "8,12")])
3402 (define_insn_and_split "*and<mode>3_2insn_dot2"
3403   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3404         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3405                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3406                     (const_int 0)))
3407    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3408         (and:GPR (match_dup 1)
3409                  (match_dup 2)))]
3410   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3411    && rs6000_gen_cell_microcode
3412    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3413    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3414         || (logical_const_operand (operands[2], <MODE>mode)
3415             && rs6000_gen_cell_microcode))"
3416   "#"
3417   "&& reload_completed"
3418   [(pc)]
3420   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3421   DONE;
3423   [(set_attr "type" "shift")
3424    (set_attr "dot" "yes")
3425    (set_attr "length" "8,12")])
3428 (define_expand "<code><mode>3"
3429   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3430         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3431                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3432   ""
3434   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3435     {
3436       rs6000_split_logical (operands, <CODE>, false, false, false);
3437       DONE;
3438     }
3440   if (non_logical_cint_operand (operands[2], <MODE>mode))
3441     {
3442       rtx tmp = ((!can_create_pseudo_p ()
3443                   || rtx_equal_p (operands[0], operands[1]))
3444                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3446       HOST_WIDE_INT value = INTVAL (operands[2]);
3447       HOST_WIDE_INT lo = value & 0xffff;
3448       HOST_WIDE_INT hi = value - lo;
3450       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3451       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3452       DONE;
3453     }
3455   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3456     operands[2] = force_reg (<MODE>mode, operands[2]);
3459 (define_split
3460   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3461         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3462                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3463   ""
3464   [(set (match_dup 3)
3465         (iorxor:GPR (match_dup 1)
3466                     (match_dup 4)))
3467    (set (match_dup 0)
3468         (iorxor:GPR (match_dup 3)
3469                     (match_dup 5)))]
3471   operands[3] = ((!can_create_pseudo_p ()
3472                   || rtx_equal_p (operands[0], operands[1]))
3473                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3475   HOST_WIDE_INT value = INTVAL (operands[2]);
3476   HOST_WIDE_INT lo = value & 0xffff;
3477   HOST_WIDE_INT hi = value - lo;
3479   operands[4] = GEN_INT (hi);
3480   operands[5] = GEN_INT (lo);
3483 (define_insn "*bool<mode>3_imm"
3484   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3485         (match_operator:GPR 3 "boolean_or_operator"
3486          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3487           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3488   ""
3489   "%q3i%e2 %0,%1,%u2"
3490   [(set_attr "type" "logical")])
3492 (define_insn "*bool<mode>3"
3493   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3494         (match_operator:GPR 3 "boolean_operator"
3495          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3496           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3497   ""
3498   "%q3 %0,%1,%2"
3499   [(set_attr "type" "logical")])
3501 (define_insn_and_split "*bool<mode>3_dot"
3502   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3503         (compare:CC (match_operator:GPR 3 "boolean_operator"
3504          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3505           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3506          (const_int 0)))
3507    (clobber (match_scratch:GPR 0 "=r,r"))]
3508   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3509   "@
3510    %q3. %0,%1,%2
3511    #"
3512   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3513   [(set (match_dup 0)
3514         (match_dup 3))
3515    (set (match_dup 4)
3516         (compare:CC (match_dup 0)
3517                     (const_int 0)))]
3518   ""
3519   [(set_attr "type" "logical")
3520    (set_attr "dot" "yes")
3521    (set_attr "length" "4,8")])
3523 (define_insn_and_split "*bool<mode>3_dot2"
3524   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3525         (compare:CC (match_operator:GPR 3 "boolean_operator"
3526          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3527           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3528          (const_int 0)))
3529    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3530         (match_dup 3))]
3531   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3532   "@
3533    %q3. %0,%1,%2
3534    #"
3535   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3536   [(set (match_dup 0)
3537         (match_dup 3))
3538    (set (match_dup 4)
3539         (compare:CC (match_dup 0)
3540                     (const_int 0)))]
3541   ""
3542   [(set_attr "type" "logical")
3543    (set_attr "dot" "yes")
3544    (set_attr "length" "4,8")])
3547 (define_insn "*boolc<mode>3"
3548   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3549         (match_operator:GPR 3 "boolean_operator"
3550          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3551           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3552   ""
3553   "%q3 %0,%1,%2"
3554   [(set_attr "type" "logical")])
3556 (define_insn_and_split "*boolc<mode>3_dot"
3557   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3558         (compare:CC (match_operator:GPR 3 "boolean_operator"
3559          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3560           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3561          (const_int 0)))
3562    (clobber (match_scratch:GPR 0 "=r,r"))]
3563   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3564   "@
3565    %q3. %0,%1,%2
3566    #"
3567   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3568   [(set (match_dup 0)
3569         (match_dup 3))
3570    (set (match_dup 4)
3571         (compare:CC (match_dup 0)
3572                     (const_int 0)))]
3573   ""
3574   [(set_attr "type" "logical")
3575    (set_attr "dot" "yes")
3576    (set_attr "length" "4,8")])
3578 (define_insn_and_split "*boolc<mode>3_dot2"
3579   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3580         (compare:CC (match_operator:GPR 3 "boolean_operator"
3581          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3582           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3583          (const_int 0)))
3584    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3585         (match_dup 3))]
3586   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3587   "@
3588    %q3. %0,%1,%2
3589    #"
3590   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3591   [(set (match_dup 0)
3592         (match_dup 3))
3593    (set (match_dup 4)
3594         (compare:CC (match_dup 0)
3595                     (const_int 0)))]
3596   ""
3597   [(set_attr "type" "logical")
3598    (set_attr "dot" "yes")
3599    (set_attr "length" "4,8")])
3602 (define_insn "*boolcc<mode>3"
3603   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3604         (match_operator:GPR 3 "boolean_operator"
3605          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3606           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3607   ""
3608   "%q3 %0,%1,%2"
3609   [(set_attr "type" "logical")])
3611 (define_insn_and_split "*boolcc<mode>3_dot"
3612   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3613         (compare:CC (match_operator:GPR 3 "boolean_operator"
3614          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3615           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3616          (const_int 0)))
3617    (clobber (match_scratch:GPR 0 "=r,r"))]
3618   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3619   "@
3620    %q3. %0,%1,%2
3621    #"
3622   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3623   [(set (match_dup 0)
3624         (match_dup 3))
3625    (set (match_dup 4)
3626         (compare:CC (match_dup 0)
3627                     (const_int 0)))]
3628   ""
3629   [(set_attr "type" "logical")
3630    (set_attr "dot" "yes")
3631    (set_attr "length" "4,8")])
3633 (define_insn_and_split "*boolcc<mode>3_dot2"
3634   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3635         (compare:CC (match_operator:GPR 3 "boolean_operator"
3636          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3637           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3638          (const_int 0)))
3639    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3640         (match_dup 3))]
3641   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3642   "@
3643    %q3. %0,%1,%2
3644    #"
3645   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3646   [(set (match_dup 0)
3647         (match_dup 3))
3648    (set (match_dup 4)
3649         (compare:CC (match_dup 0)
3650                     (const_int 0)))]
3651   ""
3652   [(set_attr "type" "logical")
3653    (set_attr "dot" "yes")
3654    (set_attr "length" "4,8")])
3657 ;; TODO: Should have dots of this as well.
3658 (define_insn "*eqv<mode>3"
3659   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3660         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3661                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3662   ""
3663   "eqv %0,%1,%2"
3664   [(set_attr "type" "logical")])
3666 ;; Rotate-and-mask and insert.
3668 (define_insn "*rotl<mode>3_mask"
3669   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3670         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3671                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3672                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3673                  (match_operand:GPR 3 "const_int_operand" "n")))]
3674   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3676   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3678   [(set_attr "type" "shift")
3679    (set_attr "maybe_var_shift" "yes")])
3681 (define_insn_and_split "*rotl<mode>3_mask_dot"
3682   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3683         (compare:CC
3684           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3685                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3686                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3687                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3688           (const_int 0)))
3689    (clobber (match_scratch:GPR 0 "=r,r"))]
3690   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3691    && rs6000_gen_cell_microcode
3692    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3694   if (which_alternative == 0)
3695     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3696   else
3697     return "#";
3699   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3700   [(set (match_dup 0)
3701         (and:GPR (match_dup 4)
3702                  (match_dup 3)))
3703    (set (match_dup 5)
3704         (compare:CC (match_dup 0)
3705                     (const_int 0)))]
3706   ""
3707   [(set_attr "type" "shift")
3708    (set_attr "maybe_var_shift" "yes")
3709    (set_attr "dot" "yes")
3710    (set_attr "length" "4,8")])
3712 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3713   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3714         (compare:CC
3715           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3716                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3717                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3718                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3719           (const_int 0)))
3720    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3721         (and:GPR (match_dup 4)
3722                  (match_dup 3)))]
3723   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3724    && rs6000_gen_cell_microcode
3725    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3727   if (which_alternative == 0)
3728     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3729   else
3730     return "#";
3732   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3733   [(set (match_dup 0)
3734         (and:GPR (match_dup 4)
3735                  (match_dup 3)))
3736    (set (match_dup 5)
3737         (compare:CC (match_dup 0)
3738                     (const_int 0)))]
3739   ""
3740   [(set_attr "type" "shift")
3741    (set_attr "maybe_var_shift" "yes")
3742    (set_attr "dot" "yes")
3743    (set_attr "length" "4,8")])
3745 ; Special case for less-than-0.  We can do it with just one machine
3746 ; instruction, but the generic optimizers do not realise it is cheap.
3747 (define_insn "*lt0_disi"
3748   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3749         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3750                (const_int 0)))]
3751   "TARGET_POWERPC64"
3752   "rlwinm %0,%1,1,31,31"
3753   [(set_attr "type" "shift")])
3757 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3758 ; both are an AND so are the same precedence).
3759 (define_insn "*rotl<mode>3_insert"
3760   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3761         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3762                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3763                             (match_operand:SI 2 "const_int_operand" "n")])
3764                           (match_operand:GPR 3 "const_int_operand" "n"))
3765                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3766                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3767   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3768    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3770   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3772   [(set_attr "type" "insert")])
3773 ; FIXME: this needs an attr "size", so that the scheduler can see the
3774 ; difference between rlwimi and rldimi.  We also might want dot forms,
3775 ; but not for rlwimi on POWER4 and similar processors.
3777 (define_insn "*rotl<mode>3_insert_2"
3778   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3779         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3780                           (match_operand:GPR 6 "const_int_operand" "n"))
3781                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3782                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3783                             (match_operand:SI 2 "const_int_operand" "n")])
3784                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3785   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3786    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3788   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3790   [(set_attr "type" "insert")])
3792 ; There are also some forms without one of the ANDs.
3793 (define_insn "*rotl<mode>3_insert_3"
3794   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3795         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3796                           (match_operand:GPR 4 "const_int_operand" "n"))
3797                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3798                              (match_operand:SI 2 "const_int_operand" "n"))))]
3799   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3801   if (<MODE>mode == SImode)
3802     return "rlwimi %0,%1,%h2,0,31-%h2";
3803   else
3804     return "rldimi %0,%1,%H2,0";
3806   [(set_attr "type" "insert")])
3808 (define_insn "*rotl<mode>3_insert_4"
3809   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3810         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3811                           (match_operand:GPR 4 "const_int_operand" "n"))
3812                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3813                                (match_operand:SI 2 "const_int_operand" "n"))))]
3814   "<MODE>mode == SImode &&
3815    GET_MODE_PRECISION (<MODE>mode)
3816    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3818   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3819                          - INTVAL (operands[2]));
3820   if (<MODE>mode == SImode)
3821     return "rlwimi %0,%1,%h2,32-%h2,31";
3822   else
3823     return "rldimi %0,%1,%H2,64-%H2";
3825   [(set_attr "type" "insert")])
3828 ; This handles the important case of multiple-precision shifts.  There is
3829 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3830 (define_split
3831   [(set (match_operand:GPR 0 "gpc_reg_operand")
3832         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3833                              (match_operand:SI 3 "const_int_operand"))
3834                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3835                                (match_operand:SI 4 "const_int_operand"))))]
3836   "can_create_pseudo_p ()
3837    && INTVAL (operands[3]) + INTVAL (operands[4])
3838       >= GET_MODE_PRECISION (<MODE>mode)"
3839   [(set (match_dup 5)
3840         (lshiftrt:GPR (match_dup 2)
3841                       (match_dup 4)))
3842    (set (match_dup 0)
3843         (ior:GPR (and:GPR (match_dup 5)
3844                           (match_dup 6))
3845                  (ashift:GPR (match_dup 1)
3846                              (match_dup 3))))]
3848   unsigned HOST_WIDE_INT mask = 1;
3849   mask = (mask << INTVAL (operands[3])) - 1;
3850   operands[5] = gen_reg_rtx (<MODE>mode);
3851   operands[6] = GEN_INT (mask);
3854 (define_split
3855   [(set (match_operand:GPR 0 "gpc_reg_operand")
3856         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3857                                (match_operand:SI 4 "const_int_operand"))
3858                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3859                              (match_operand:SI 3 "const_int_operand"))))]
3860   "can_create_pseudo_p ()
3861    && INTVAL (operands[3]) + INTVAL (operands[4])
3862       >= GET_MODE_PRECISION (<MODE>mode)"
3863   [(set (match_dup 5)
3864         (lshiftrt:GPR (match_dup 2)
3865                       (match_dup 4)))
3866    (set (match_dup 0)
3867         (ior:GPR (and:GPR (match_dup 5)
3868                           (match_dup 6))
3869                  (ashift:GPR (match_dup 1)
3870                              (match_dup 3))))]
3872   unsigned HOST_WIDE_INT mask = 1;
3873   mask = (mask << INTVAL (operands[3])) - 1;
3874   operands[5] = gen_reg_rtx (<MODE>mode);
3875   operands[6] = GEN_INT (mask);
3879 ; Another important case is setting some bits to 1; we can do that with
3880 ; an insert instruction, in many cases.
3881 (define_insn_and_split "*ior<mode>_mask"
3882   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3883         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3884                  (match_operand:GPR 2 "const_int_operand" "n")))
3885    (clobber (match_scratch:GPR 3 "=r"))]
3886   "!logical_const_operand (operands[2], <MODE>mode)
3887    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3888   "#"
3889   "&& 1"
3890   [(set (match_dup 3)
3891         (const_int -1))
3892    (set (match_dup 0)
3893         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3894                                       (match_dup 4))
3895                           (match_dup 2))
3896                  (and:GPR (match_dup 1)
3897                           (match_dup 5))))]
3899   int nb, ne;
3900   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3901   if (GET_CODE (operands[3]) == SCRATCH)
3902     operands[3] = gen_reg_rtx (<MODE>mode);
3903   operands[4] = GEN_INT (ne);
3904   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3906   [(set_attr "type" "two")
3907    (set_attr "length" "8")])
3910 ;; Now the simple shifts.
3912 (define_insn "rotl<mode>3"
3913   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3914         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3915                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3916   ""
3917   "rotl<wd>%I2 %0,%1,%<hH>2"
3918   [(set_attr "type" "shift")
3919    (set_attr "maybe_var_shift" "yes")])
3921 (define_insn "*rotlsi3_64"
3922   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3923         (zero_extend:DI
3924             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3925                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3926   "TARGET_POWERPC64"
3927   "rotlw%I2 %0,%1,%h2"
3928   [(set_attr "type" "shift")
3929    (set_attr "maybe_var_shift" "yes")])
3931 (define_insn_and_split "*rotl<mode>3_dot"
3932   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3933         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3934                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3935                     (const_int 0)))
3936    (clobber (match_scratch:GPR 0 "=r,r"))]
3937   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3938   "@
3939    rotl<wd>%I2. %0,%1,%<hH>2
3940    #"
3941   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3942   [(set (match_dup 0)
3943         (rotate:GPR (match_dup 1)
3944                     (match_dup 2)))
3945    (set (match_dup 3)
3946         (compare:CC (match_dup 0)
3947                     (const_int 0)))]
3948   ""
3949   [(set_attr "type" "shift")
3950    (set_attr "maybe_var_shift" "yes")
3951    (set_attr "dot" "yes")
3952    (set_attr "length" "4,8")])
3954 (define_insn_and_split "*rotl<mode>3_dot2"
3955   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3956         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3957                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3958                     (const_int 0)))
3959    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3960         (rotate:GPR (match_dup 1)
3961                     (match_dup 2)))]
3962   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3963   "@
3964    rotl<wd>%I2. %0,%1,%<hH>2
3965    #"
3966   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3967   [(set (match_dup 0)
3968         (rotate:GPR (match_dup 1)
3969                     (match_dup 2)))
3970    (set (match_dup 3)
3971         (compare:CC (match_dup 0)
3972                     (const_int 0)))]
3973   ""
3974   [(set_attr "type" "shift")
3975    (set_attr "maybe_var_shift" "yes")
3976    (set_attr "dot" "yes")
3977    (set_attr "length" "4,8")])
3980 (define_insn "ashl<mode>3"
3981   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3982         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3983                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3984   ""
3985   "sl<wd>%I2 %0,%1,%<hH>2"
3986   [(set_attr "type" "shift")
3987    (set_attr "maybe_var_shift" "yes")])
3989 (define_insn "*ashlsi3_64"
3990   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3991         (zero_extend:DI
3992             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3993                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3994   "TARGET_POWERPC64"
3995   "slw%I2 %0,%1,%h2"
3996   [(set_attr "type" "shift")
3997    (set_attr "maybe_var_shift" "yes")])
3999 (define_insn_and_split "*ashl<mode>3_dot"
4000   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4001         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4002                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4003                     (const_int 0)))
4004    (clobber (match_scratch:GPR 0 "=r,r"))]
4005   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4006   "@
4007    sl<wd>%I2. %0,%1,%<hH>2
4008    #"
4009   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4010   [(set (match_dup 0)
4011         (ashift:GPR (match_dup 1)
4012                     (match_dup 2)))
4013    (set (match_dup 3)
4014         (compare:CC (match_dup 0)
4015                     (const_int 0)))]
4016   ""
4017   [(set_attr "type" "shift")
4018    (set_attr "maybe_var_shift" "yes")
4019    (set_attr "dot" "yes")
4020    (set_attr "length" "4,8")])
4022 (define_insn_and_split "*ashl<mode>3_dot2"
4023   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4024         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4025                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4026                     (const_int 0)))
4027    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4028         (ashift:GPR (match_dup 1)
4029                     (match_dup 2)))]
4030   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4031   "@
4032    sl<wd>%I2. %0,%1,%<hH>2
4033    #"
4034   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4035   [(set (match_dup 0)
4036         (ashift:GPR (match_dup 1)
4037                     (match_dup 2)))
4038    (set (match_dup 3)
4039         (compare:CC (match_dup 0)
4040                     (const_int 0)))]
4041   ""
4042   [(set_attr "type" "shift")
4043    (set_attr "maybe_var_shift" "yes")
4044    (set_attr "dot" "yes")
4045    (set_attr "length" "4,8")])
4047 ;; Pretend we have a memory form of extswsli until register allocation is done
4048 ;; so that we use LWZ to load the value from memory, instead of LWA.
4049 (define_insn_and_split "ashdi3_extswsli"
4050   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4051         (ashift:DI
4052          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4053          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4054   "TARGET_EXTSWSLI"
4055   "@
4056    extswsli %0,%1,%2
4057    #"
4058   "&& reload_completed && MEM_P (operands[1])"
4059   [(set (match_dup 3)
4060         (match_dup 1))
4061    (set (match_dup 0)
4062         (ashift:DI (sign_extend:DI (match_dup 3))
4063                    (match_dup 2)))]
4065   operands[3] = gen_lowpart (SImode, operands[0]);
4067   [(set_attr "type" "shift")
4068    (set_attr "maybe_var_shift" "no")])
4071 (define_insn_and_split "ashdi3_extswsli_dot"
4072   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4073         (compare:CC
4074          (ashift:DI
4075           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4076           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4077          (const_int 0)))
4078    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4079   "TARGET_EXTSWSLI"
4080   "@
4081    extswsli. %0,%1,%2
4082    #
4083    #
4084    #"
4085   "&& reload_completed
4086    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4087        || memory_operand (operands[1], SImode))"
4088   [(pc)]
4090   rtx dest = operands[0];
4091   rtx src = operands[1];
4092   rtx shift = operands[2];
4093   rtx cr = operands[3];
4094   rtx src2;
4096   if (!MEM_P (src))
4097     src2 = src;
4098   else
4099     {
4100       src2 = gen_lowpart (SImode, dest);
4101       emit_move_insn (src2, src);
4102     }
4104   if (REGNO (cr) == CR0_REGNO)
4105     {
4106       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4107       DONE;
4108     }
4110   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4111   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4112   DONE;
4114   [(set_attr "type" "shift")
4115    (set_attr "maybe_var_shift" "no")
4116    (set_attr "dot" "yes")
4117    (set_attr "length" "4,8,8,12")])
4119 (define_insn_and_split "ashdi3_extswsli_dot2"
4120   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4121         (compare:CC
4122          (ashift:DI
4123           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4124           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4125          (const_int 0)))
4126    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4127         (ashift:DI (sign_extend:DI (match_dup 1))
4128                    (match_dup 2)))]
4129   "TARGET_EXTSWSLI"
4130   "@
4131    extswsli. %0,%1,%2
4132    #
4133    #
4134    #"
4135   "&& reload_completed
4136    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4137        || memory_operand (operands[1], SImode))"
4138   [(pc)]
4140   rtx dest = operands[0];
4141   rtx src = operands[1];
4142   rtx shift = operands[2];
4143   rtx cr = operands[3];
4144   rtx src2;
4146   if (!MEM_P (src))
4147     src2 = src;
4148   else
4149     {
4150       src2 = gen_lowpart (SImode, dest);
4151       emit_move_insn (src2, src);
4152     }
4154   if (REGNO (cr) == CR0_REGNO)
4155     {
4156       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4157       DONE;
4158     }
4160   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4161   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4162   DONE;
4164   [(set_attr "type" "shift")
4165    (set_attr "maybe_var_shift" "no")
4166    (set_attr "dot" "yes")
4167    (set_attr "length" "4,8,8,12")])
4169 (define_insn "lshr<mode>3"
4170   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4171         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4172                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4173   ""
4174   "sr<wd>%I2 %0,%1,%<hH>2"
4175   [(set_attr "type" "shift")
4176    (set_attr "maybe_var_shift" "yes")])
4178 (define_insn "*lshrsi3_64"
4179   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4180         (zero_extend:DI
4181             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4182                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4183   "TARGET_POWERPC64"
4184   "srw%I2 %0,%1,%h2"
4185   [(set_attr "type" "shift")
4186    (set_attr "maybe_var_shift" "yes")])
4188 (define_insn_and_split "*lshr<mode>3_dot"
4189   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4190         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4191                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4192                     (const_int 0)))
4193    (clobber (match_scratch:GPR 0 "=r,r"))]
4194   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4195   "@
4196    sr<wd>%I2. %0,%1,%<hH>2
4197    #"
4198   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4199   [(set (match_dup 0)
4200         (lshiftrt:GPR (match_dup 1)
4201                       (match_dup 2)))
4202    (set (match_dup 3)
4203         (compare:CC (match_dup 0)
4204                     (const_int 0)))]
4205   ""
4206   [(set_attr "type" "shift")
4207    (set_attr "maybe_var_shift" "yes")
4208    (set_attr "dot" "yes")
4209    (set_attr "length" "4,8")])
4211 (define_insn_and_split "*lshr<mode>3_dot2"
4212   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4213         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4214                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4215                     (const_int 0)))
4216    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4217         (lshiftrt:GPR (match_dup 1)
4218                       (match_dup 2)))]
4219   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4220   "@
4221    sr<wd>%I2. %0,%1,%<hH>2
4222    #"
4223   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4224   [(set (match_dup 0)
4225         (lshiftrt:GPR (match_dup 1)
4226                       (match_dup 2)))
4227    (set (match_dup 3)
4228         (compare:CC (match_dup 0)
4229                     (const_int 0)))]
4230   ""
4231   [(set_attr "type" "shift")
4232    (set_attr "maybe_var_shift" "yes")
4233    (set_attr "dot" "yes")
4234    (set_attr "length" "4,8")])
4237 (define_insn "ashr<mode>3"
4238   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4239         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4240                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4241    (clobber (reg:GPR CA_REGNO))]
4242   ""
4243   "sra<wd>%I2 %0,%1,%<hH>2"
4244   [(set_attr "type" "shift")
4245    (set_attr "maybe_var_shift" "yes")])
4247 (define_insn "*ashrsi3_64"
4248   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4249         (sign_extend:DI
4250             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4251                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4252    (clobber (reg:SI CA_REGNO))]
4253   "TARGET_POWERPC64"
4254   "sraw%I2 %0,%1,%h2"
4255   [(set_attr "type" "shift")
4256    (set_attr "maybe_var_shift" "yes")])
4258 (define_insn_and_split "*ashr<mode>3_dot"
4259   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4260         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4261                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4262                     (const_int 0)))
4263    (clobber (match_scratch:GPR 0 "=r,r"))
4264    (clobber (reg:GPR CA_REGNO))]
4265   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4266   "@
4267    sra<wd>%I2. %0,%1,%<hH>2
4268    #"
4269   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4270   [(parallel [(set (match_dup 0)
4271                    (ashiftrt:GPR (match_dup 1)
4272                                  (match_dup 2)))
4273               (clobber (reg:GPR CA_REGNO))])
4274    (set (match_dup 3)
4275         (compare:CC (match_dup 0)
4276                     (const_int 0)))]
4277   ""
4278   [(set_attr "type" "shift")
4279    (set_attr "maybe_var_shift" "yes")
4280    (set_attr "dot" "yes")
4281    (set_attr "length" "4,8")])
4283 (define_insn_and_split "*ashr<mode>3_dot2"
4284   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4285         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4286                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4287                     (const_int 0)))
4288    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4289         (ashiftrt:GPR (match_dup 1)
4290                       (match_dup 2)))
4291    (clobber (reg:GPR CA_REGNO))]
4292   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4293   "@
4294    sra<wd>%I2. %0,%1,%<hH>2
4295    #"
4296   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4297   [(parallel [(set (match_dup 0)
4298                    (ashiftrt:GPR (match_dup 1)
4299                                  (match_dup 2)))
4300               (clobber (reg:GPR CA_REGNO))])
4301    (set (match_dup 3)
4302         (compare:CC (match_dup 0)
4303                     (const_int 0)))]
4304   ""
4305   [(set_attr "type" "shift")
4306    (set_attr "maybe_var_shift" "yes")
4307    (set_attr "dot" "yes")
4308    (set_attr "length" "4,8")])
4310 ;; Builtins to replace a division to generate FRE reciprocal estimate
4311 ;; instructions and the necessary fixup instructions
4312 (define_expand "recip<mode>3"
4313   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4314    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4315    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4316   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4318    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4319    DONE;
4322 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4323 ;; hardware division.  This is only done before register allocation and with
4324 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4325 (define_split
4326   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4327         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4328                     (match_operand 2 "gpc_reg_operand" "")))]
4329   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4330    && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4331    && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4332   [(const_int 0)]
4334   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4335   DONE;
4338 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4339 ;; appropriate fixup.
4340 (define_expand "rsqrt<mode>2"
4341   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4342    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4343   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4345   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4346   DONE;
4349 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4350 ;; modes here, and also add in conditional vsx/power8-vector support to access
4351 ;; values in the traditional Altivec registers if the appropriate
4352 ;; -mupper-regs-{df,sf} option is enabled.
4354 (define_expand "abs<mode>2"
4355   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4356         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4357   "TARGET_<MODE>_INSN"
4358   "")
4360 (define_insn "*abs<mode>2_fpr"
4361   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4362         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4363   "TARGET_<MODE>_FPR"
4364   "@
4365    fabs %0,%1
4366    xsabsdp %x0,%x1"
4367   [(set_attr "type" "fpsimple")
4368    (set_attr "fp_type" "fp_addsub_<Fs>")])
4370 (define_insn "*nabs<mode>2_fpr"
4371   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4372         (neg:SFDF
4373          (abs:SFDF
4374           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4375   "TARGET_<MODE>_FPR"
4376   "@
4377    fnabs %0,%1
4378    xsnabsdp %x0,%x1"
4379   [(set_attr "type" "fpsimple")
4380    (set_attr "fp_type" "fp_addsub_<Fs>")])
4382 (define_expand "neg<mode>2"
4383   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4384         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4385   "TARGET_<MODE>_INSN"
4386   "")
4388 (define_insn "*neg<mode>2_fpr"
4389   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4390         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4391   "TARGET_<MODE>_FPR"
4392   "@
4393    fneg %0,%1
4394    xsnegdp %x0,%x1"
4395   [(set_attr "type" "fpsimple")
4396    (set_attr "fp_type" "fp_addsub_<Fs>")])
4398 (define_expand "add<mode>3"
4399   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4400         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4401                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4402   "TARGET_<MODE>_INSN"
4403   "")
4405 (define_insn "*add<mode>3_fpr"
4406   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4407         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4408                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4409   "TARGET_<MODE>_FPR"
4410   "@
4411    fadd<Ftrad> %0,%1,%2
4412    xsadd<Fvsx> %x0,%x1,%x2"
4413   [(set_attr "type" "fp")
4414    (set_attr "fp_type" "fp_addsub_<Fs>")])
4416 (define_expand "sub<mode>3"
4417   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4418         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4419                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4420   "TARGET_<MODE>_INSN"
4421   "")
4423 (define_insn "*sub<mode>3_fpr"
4424   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4425         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4426                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4427   "TARGET_<MODE>_FPR"
4428   "@
4429    fsub<Ftrad> %0,%1,%2
4430    xssub<Fvsx> %x0,%x1,%x2"
4431   [(set_attr "type" "fp")
4432    (set_attr "fp_type" "fp_addsub_<Fs>")])
4434 (define_expand "mul<mode>3"
4435   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4436         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4437                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4438   "TARGET_<MODE>_INSN"
4439   "")
4441 (define_insn "*mul<mode>3_fpr"
4442   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4443         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4444                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4445   "TARGET_<MODE>_FPR"
4446   "@
4447    fmul<Ftrad> %0,%1,%2
4448    xsmul<Fvsx> %x0,%x1,%x2"
4449   [(set_attr "type" "dmul")
4450    (set_attr "fp_type" "fp_mul_<Fs>")])
4452 (define_expand "div<mode>3"
4453   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4454         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4455                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4456   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4457   "")
4459 (define_insn "*div<mode>3_fpr"
4460   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4461         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4462                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4463   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4464   "@
4465    fdiv<Ftrad> %0,%1,%2
4466    xsdiv<Fvsx> %x0,%x1,%x2"
4467   [(set_attr "type" "<Fs>div")
4468    (set_attr "fp_type" "fp_div_<Fs>")])
4470 (define_insn "*sqrt<mode>2_internal"
4471   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4472         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4473   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4474    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4475   "@
4476    fsqrt<Ftrad> %0,%1
4477    xssqrt<Fvsx> %x0,%x1"
4478   [(set_attr "type" "<Fs>sqrt")
4479    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4481 (define_expand "sqrt<mode>2"
4482   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4483         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4484   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4485    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4487   if (<MODE>mode == SFmode
4488       && TARGET_RECIP_PRECISION
4489       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4490       && !optimize_function_for_size_p (cfun)
4491       && flag_finite_math_only && !flag_trapping_math
4492       && flag_unsafe_math_optimizations)
4493     {
4494       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4495       DONE;
4496     }
4499 ;; Floating point reciprocal approximation
4500 (define_insn "fre<Fs>"
4501   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4502         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4503                      UNSPEC_FRES))]
4504   "TARGET_<FFRE>"
4505   "@
4506    fre<Ftrad> %0,%1
4507    xsre<Fvsx> %x0,%x1"
4508   [(set_attr "type" "fp")])
4510 (define_insn "*rsqrt<mode>2"
4511   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4512         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4513                      UNSPEC_RSQRT))]
4514   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4515   "@
4516    frsqrte<Ftrad> %0,%1
4517    xsrsqrte<Fvsx> %x0,%x1"
4518   [(set_attr "type" "fp")])
4520 ;; Floating point comparisons
4521 (define_insn "*cmp<mode>_fpr"
4522   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4523         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4524                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4525   "TARGET_<MODE>_FPR"
4526   "@
4527    fcmpu %0,%1,%2
4528    xscmpudp %0,%x1,%x2"
4529   [(set_attr "type" "fpcompare")])
4531 ;; Floating point conversions
4532 (define_expand "extendsfdf2"
4533   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4534         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4535   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4536   "")
4538 (define_insn_and_split "*extendsfdf2_fpr"
4539   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4540         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4541   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4542   "@
4543    #
4544    fmr %0,%1
4545    lfs%U1%X1 %0,%1
4546    #
4547    xscpsgndp %x0,%x1,%x1
4548    lxsspx %x0,%y1
4549    lxssp %0,%1"
4550   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4551   [(const_int 0)]
4553   emit_note (NOTE_INSN_DELETED);
4554   DONE;
4556   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4558 (define_expand "truncdfsf2"
4559   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4560         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4561   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4562   "")
4564 (define_insn "*truncdfsf2_fpr"
4565   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4566         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4567   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4568   "@
4569    frsp %0,%1
4570    xsrsp %x0,%x1"
4571   [(set_attr "type" "fp")])
4573 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4574 ;; builtins.c and optabs.c that are not correct for IBM long double
4575 ;; when little-endian.
4576 (define_expand "signbit<mode>2"
4577   [(set (match_dup 2)
4578         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4579    (set (match_dup 3)
4580         (subreg:DI (match_dup 2) 0))
4581    (set (match_dup 4)
4582         (match_dup 5))
4583    (set (match_operand:SI 0 "gpc_reg_operand" "")
4584         (match_dup 6))]
4585   "TARGET_HARD_FLOAT
4586    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4587    && (!FLOAT128_IEEE_P (<MODE>mode)
4588        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4590   if (FLOAT128_IEEE_P (<MODE>mode))
4591     {
4592       if (<MODE>mode == KFmode)
4593         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4594       else if (<MODE>mode == TFmode)
4595         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4596       else
4597         gcc_unreachable ();
4598       DONE;
4599     }
4600   operands[2] = gen_reg_rtx (DFmode);
4601   operands[3] = gen_reg_rtx (DImode);
4602   if (TARGET_POWERPC64)
4603     {
4604       operands[4] = gen_reg_rtx (DImode);
4605       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4606       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4607                                     WORDS_BIG_ENDIAN ? 4 : 0);
4608     }
4609   else
4610     {
4611       operands[4] = gen_reg_rtx (SImode);
4612       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4613                                     WORDS_BIG_ENDIAN ? 0 : 4);
4614       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4615     }
4618 (define_expand "copysign<mode>3"
4619   [(set (match_dup 3)
4620         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4621    (set (match_dup 4)
4622         (neg:SFDF (abs:SFDF (match_dup 1))))
4623    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4624         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4625                                (match_dup 5))
4626                          (match_dup 3)
4627                          (match_dup 4)))]
4628   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4629    && ((TARGET_PPC_GFXOPT
4630         && !HONOR_NANS (<MODE>mode)
4631         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4632        || TARGET_CMPB
4633        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4635   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4636     {
4637       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4638                                              operands[2]));
4639       DONE;
4640     }
4642    operands[3] = gen_reg_rtx (<MODE>mode);
4643    operands[4] = gen_reg_rtx (<MODE>mode);
4644    operands[5] = CONST0_RTX (<MODE>mode);
4645   })
4647 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4648 ;; and load.
4649 (define_insn_and_split "signbit<mode>2_dm"
4650   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4651         (unspec:SI
4652          [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4653          UNSPEC_SIGNBIT))]
4654   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4655   "#"
4656   "&& reload_completed"
4657   [(const_int 0)]
4659   rs6000_split_signbit (operands[0], operands[1]);
4660   DONE;
4662  [(set_attr "length" "8,8,12")
4663   (set_attr "type" "mftgpr,load,integer")])
4665 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4666 ;; point types, which makes normal SUBREG's problematical. Instead use a
4667 ;; special pattern to avoid using a normal movdi.
4668 (define_insn "signbit<mode>2_dm2"
4669   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4670         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4671                     (const_int 0)]
4672                    UNSPEC_SIGNBIT))]
4673   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4674   "mfvsrd %0,%x1"
4675  [(set_attr "type" "mftgpr")])
4678 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4679 ;; compiler from optimizing -0.0
4680 (define_insn "copysign<mode>3_fcpsgn"
4681   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4682         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4683                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4684                      UNSPEC_COPYSIGN))]
4685   "TARGET_<MODE>_FPR && TARGET_CMPB"
4686   "@
4687    fcpsgn %0,%2,%1
4688    xscpsgndp %x0,%x2,%x1"
4689   [(set_attr "type" "fpsimple")])
4691 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4692 ;; fsel instruction and some auxiliary computations.  Then we just have a
4693 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4694 ;; combine.
4695 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4696 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4697 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4698 ;; define_splits to make them if made by combine.  On VSX machines we have the
4699 ;; min/max instructions.
4701 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4702 ;; to allow either DF/SF to use only traditional registers.
4704 (define_expand "s<minmax><mode>3"
4705   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4706         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4707                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4708   "TARGET_MINMAX_<MODE>"
4710   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4711   DONE;
4714 (define_insn "*s<minmax><mode>3_vsx"
4715   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4716         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4717                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4718   "TARGET_VSX && TARGET_<MODE>_FPR"
4720   return (TARGET_P9_MINMAX
4721           ? "xs<minmax>cdp %x0,%x1,%x2"
4722           : "xs<minmax>dp %x0,%x1,%x2");
4724   [(set_attr "type" "fp")])
4726 ;; The conditional move instructions allow us to perform max and min operations
4727 ;; even when we don't have the appropriate max/min instruction using the FSEL
4728 ;; instruction.
4730 (define_insn_and_split "*s<minmax><mode>3_fpr"
4731   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4732         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4733                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4734   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4735   "#"
4736   "&& 1"
4737   [(const_int 0)]
4739   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4740   DONE;
4743 (define_expand "mov<mode>cc"
4744    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4745          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4746                            (match_operand:GPR 2 "gpc_reg_operand" "")
4747                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4748   "TARGET_ISEL<sel>"
4749   "
4751   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4752     DONE;
4753   else
4754     FAIL;
4757 ;; We use the BASE_REGS for the isel input operands because, if rA is
4758 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4759 ;; because we may switch the operands and rB may end up being rA.
4761 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4762 ;; leave out the mode in operand 4 and use one pattern, but reload can
4763 ;; change the mode underneath our feet and then gets confused trying
4764 ;; to reload the value.
4765 (define_insn "isel_signed_<mode>"
4766   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4767         (if_then_else:GPR
4768          (match_operator 1 "scc_comparison_operator"
4769                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4770                           (const_int 0)])
4771          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4772          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4773   "TARGET_ISEL<sel>"
4774   "*
4775 { return output_isel (operands); }"
4776   [(set_attr "type" "isel")
4777    (set_attr "length" "4")])
4779 (define_insn "isel_unsigned_<mode>"
4780   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4781         (if_then_else:GPR
4782          (match_operator 1 "scc_comparison_operator"
4783                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4784                           (const_int 0)])
4785          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4786          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4787   "TARGET_ISEL<sel>"
4788   "*
4789 { return output_isel (operands); }"
4790   [(set_attr "type" "isel")
4791    (set_attr "length" "4")])
4793 ;; These patterns can be useful for combine; they let combine know that
4794 ;; isel can handle reversed comparisons so long as the operands are
4795 ;; registers.
4797 (define_insn "*isel_reversed_signed_<mode>"
4798   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4799         (if_then_else:GPR
4800          (match_operator 1 "scc_rev_comparison_operator"
4801                          [(match_operand:CC 4 "cc_reg_operand" "y")
4802                           (const_int 0)])
4803          (match_operand:GPR 2 "gpc_reg_operand" "b")
4804          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4805   "TARGET_ISEL<sel>"
4806   "*
4807 { return output_isel (operands); }"
4808   [(set_attr "type" "isel")
4809    (set_attr "length" "4")])
4811 (define_insn "*isel_reversed_unsigned_<mode>"
4812   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4813         (if_then_else:GPR
4814          (match_operator 1 "scc_rev_comparison_operator"
4815                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4816                           (const_int 0)])
4817          (match_operand:GPR 2 "gpc_reg_operand" "b")
4818          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4819   "TARGET_ISEL<sel>"
4820   "*
4821 { return output_isel (operands); }"
4822   [(set_attr "type" "isel")
4823    (set_attr "length" "4")])
4825 ;; Floating point conditional move
4826 (define_expand "mov<mode>cc"
4827    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4828          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4829                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4830                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4831   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4832   "
4834   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4835     DONE;
4836   else
4837     FAIL;
4840 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4841   [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4842         (if_then_else:SFDF
4843          (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4844              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4845          (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4846          (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4847   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4848   "fsel %0,%1,%2,%3"
4849   [(set_attr "type" "fp")])
4851 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4852   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4853         (if_then_else:SFDF
4854          (match_operator:CCFP 1 "fpmask_comparison_operator"
4855                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4856                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4857          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4858          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4859    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4860   "TARGET_P9_MINMAX"
4861   "#"
4862   ""
4863   [(set (match_dup 6)
4864         (if_then_else:V2DI (match_dup 1)
4865                            (match_dup 7)
4866                            (match_dup 8)))
4867    (set (match_dup 0)
4868         (if_then_else:SFDF (ne (match_dup 6)
4869                                (match_dup 8))
4870                            (match_dup 4)
4871                            (match_dup 5)))]
4873   if (GET_CODE (operands[6]) == SCRATCH)
4874     operands[6] = gen_reg_rtx (V2DImode);
4876   operands[7] = CONSTM1_RTX (V2DImode);
4877   operands[8] = CONST0_RTX (V2DImode);
4879  [(set_attr "length" "8")
4880   (set_attr "type" "vecperm")])
4882 (define_insn "*fpmask<mode>"
4883   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4884         (if_then_else:V2DI
4885          (match_operator:CCFP 1 "fpmask_comparison_operator"
4886                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4887                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4888          (match_operand:V2DI 4 "all_ones_constant" "")
4889          (match_operand:V2DI 5 "zero_constant" "")))]
4890   "TARGET_P9_MINMAX"
4891   "xscmp%V1dp %x0,%x2,%x3"
4892   [(set_attr "type" "fpcompare")])
4894 (define_insn "*xxsel<mode>"
4895   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4896         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4897                                (match_operand:V2DI 2 "zero_constant" ""))
4898                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4899                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4900   "TARGET_P9_MINMAX"
4901   "xxsel %x0,%x1,%x3,%x4"
4902   [(set_attr "type" "vecmove")])
4905 ;; Conversions to and from floating-point.
4907 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4908 ; don't want to support putting SImode in FPR registers.
4909 (define_insn "lfiwax"
4910   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4911         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4912                    UNSPEC_LFIWAX))]
4913   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4914   "@
4915    lfiwax %0,%y1
4916    lxsiwax %x0,%y1
4917    mtvsrwa %x0,%1"
4918   [(set_attr "type" "fpload,fpload,mffgpr")])
4920 ; This split must be run before register allocation because it allocates the
4921 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4922 ; it earlier to allow for the combiner to merge insns together where it might
4923 ; not be needed and also in case the insns are deleted as dead code.
4925 (define_insn_and_split "floatsi<mode>2_lfiwax"
4926   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4927         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4928    (clobber (match_scratch:DI 2 "=wi"))]
4929   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4930    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4931   "#"
4932   ""
4933   [(pc)]
4934   "
4936   rtx dest = operands[0];
4937   rtx src = operands[1];
4938   rtx tmp;
4940   if (!MEM_P (src) && TARGET_POWERPC64
4941       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4942     tmp = convert_to_mode (DImode, src, false);
4943   else
4944     {
4945       tmp = operands[2];
4946       if (GET_CODE (tmp) == SCRATCH)
4947         tmp = gen_reg_rtx (DImode);
4948       if (MEM_P (src))
4949         {
4950           src = rs6000_address_for_fpconvert (src);
4951           emit_insn (gen_lfiwax (tmp, src));
4952         }
4953       else
4954         {
4955           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4956           emit_move_insn (stack, src);
4957           emit_insn (gen_lfiwax (tmp, stack));
4958         }
4959     }
4960   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4961   DONE;
4963   [(set_attr "length" "12")
4964    (set_attr "type" "fpload")])
4966 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4967   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4968         (float:SFDF
4969          (sign_extend:DI
4970           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
4971    (clobber (match_scratch:DI 2 "=wi"))]
4972   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4973    && <SI_CONVERT_FP>"
4974   "#"
4975   ""
4976   [(pc)]
4977   "
4979   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4980   if (GET_CODE (operands[2]) == SCRATCH)
4981     operands[2] = gen_reg_rtx (DImode);
4982   emit_insn (gen_lfiwax (operands[2], operands[1]));
4983   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4984   DONE;
4986   [(set_attr "length" "8")
4987    (set_attr "type" "fpload")])
4989 (define_insn "lfiwzx"
4990   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4991         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4992                    UNSPEC_LFIWZX))]
4993   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4994   "@
4995    lfiwzx %0,%y1
4996    lxsiwzx %x0,%y1
4997    mtvsrwz %x0,%1"
4998   [(set_attr "type" "fpload,fpload,mftgpr")])
5000 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5001   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5002         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5003    (clobber (match_scratch:DI 2 "=wi"))]
5004   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5005    && <SI_CONVERT_FP>"
5006   "#"
5007   ""
5008   [(pc)]
5009   "
5011   rtx dest = operands[0];
5012   rtx src = operands[1];
5013   rtx tmp;
5015   if (!MEM_P (src) && TARGET_POWERPC64
5016       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5017     tmp = convert_to_mode (DImode, src, true);
5018   else
5019     {
5020       tmp = operands[2];
5021       if (GET_CODE (tmp) == SCRATCH)
5022         tmp = gen_reg_rtx (DImode);
5023       if (MEM_P (src))
5024         {
5025           src = rs6000_address_for_fpconvert (src);
5026           emit_insn (gen_lfiwzx (tmp, src));
5027         }
5028       else
5029         {
5030           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5031           emit_move_insn (stack, src);
5032           emit_insn (gen_lfiwzx (tmp, stack));
5033         }
5034     }
5035   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5036   DONE;
5038   [(set_attr "length" "12")
5039    (set_attr "type" "fpload")])
5041 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5042   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5043         (unsigned_float:SFDF
5044          (zero_extend:DI
5045           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5046    (clobber (match_scratch:DI 2 "=wi"))]
5047   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5048    && <SI_CONVERT_FP>"
5049   "#"
5050   ""
5051   [(pc)]
5052   "
5054   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5055   if (GET_CODE (operands[2]) == SCRATCH)
5056     operands[2] = gen_reg_rtx (DImode);
5057   emit_insn (gen_lfiwzx (operands[2], operands[1]));
5058   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5059   DONE;
5061   [(set_attr "length" "8")
5062    (set_attr "type" "fpload")])
5064 ; For each of these conversions, there is a define_expand, a define_insn
5065 ; with a '#' template, and a define_split (with C code).  The idea is
5066 ; to allow constant folding with the template of the define_insn,
5067 ; then to have the insns split later (between sched1 and final).
5069 (define_expand "floatsidf2"
5070   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5071                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5072               (use (match_dup 2))
5073               (use (match_dup 3))
5074               (clobber (match_dup 4))
5075               (clobber (match_dup 5))
5076               (clobber (match_dup 6))])]
5077   "TARGET_HARD_FLOAT 
5078    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5079   "
5081   if (TARGET_E500_DOUBLE)
5082     {
5083       if (!REG_P (operands[1]))
5084         operands[1] = force_reg (SImode, operands[1]);
5085       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5086       DONE;
5087     }
5088   else if (TARGET_LFIWAX && TARGET_FCFID)
5089     {
5090       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5091       DONE;
5092     }
5093   else if (TARGET_FCFID)
5094     {
5095       rtx dreg = operands[1];
5096       if (!REG_P (dreg))
5097         dreg = force_reg (SImode, dreg);
5098       dreg = convert_to_mode (DImode, dreg, false);
5099       emit_insn (gen_floatdidf2 (operands[0], dreg));
5100       DONE;
5101     }
5103   if (!REG_P (operands[1]))
5104     operands[1] = force_reg (SImode, operands[1]);
5105   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5106   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5107   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5108   operands[5] = gen_reg_rtx (DFmode);
5109   operands[6] = gen_reg_rtx (SImode);
5112 (define_insn_and_split "*floatsidf2_internal"
5113   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5114         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5115    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5116    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5117    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5118    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5119    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5120   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5121   "#"
5122   ""
5123   [(pc)]
5124   "
5126   rtx lowword, highword;
5127   gcc_assert (MEM_P (operands[4]));
5128   highword = adjust_address (operands[4], SImode, 0);
5129   lowword = adjust_address (operands[4], SImode, 4);
5130   if (! WORDS_BIG_ENDIAN)
5131     std::swap (lowword, highword);
5133   emit_insn (gen_xorsi3 (operands[6], operands[1],
5134                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5135   emit_move_insn (lowword, operands[6]);
5136   emit_move_insn (highword, operands[2]);
5137   emit_move_insn (operands[5], operands[4]);
5138   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5139   DONE;
5141   [(set_attr "length" "24")
5142    (set_attr "type" "fp")])
5144 ;; If we don't have a direct conversion to single precision, don't enable this
5145 ;; conversion for 32-bit without fast math, because we don't have the insn to
5146 ;; generate the fixup swizzle to avoid double rounding problems.
5147 (define_expand "floatunssisf2"
5148   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5149         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5150   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5151    && (!TARGET_FPRS
5152        || (TARGET_FPRS
5153            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5154                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5155                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5156   "
5158   if (!TARGET_FPRS)
5159     {
5160       if (!REG_P (operands[1]))
5161         operands[1] = force_reg (SImode, operands[1]);
5162     }
5163   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5164     {
5165       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5166       DONE;
5167     }
5168   else
5169     {
5170       rtx dreg = operands[1];
5171       if (!REG_P (dreg))
5172         dreg = force_reg (SImode, dreg);
5173       dreg = convert_to_mode (DImode, dreg, true);
5174       emit_insn (gen_floatdisf2 (operands[0], dreg));
5175       DONE;
5176     }
5179 (define_expand "floatunssidf2"
5180   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5181                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5182               (use (match_dup 2))
5183               (use (match_dup 3))
5184               (clobber (match_dup 4))
5185               (clobber (match_dup 5))])]
5186   "TARGET_HARD_FLOAT
5187    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5188   "
5190   if (TARGET_E500_DOUBLE)
5191     {
5192       if (!REG_P (operands[1]))
5193         operands[1] = force_reg (SImode, operands[1]);
5194       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5195       DONE;
5196     }
5197   else if (TARGET_LFIWZX && TARGET_FCFID)
5198     {
5199       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5200       DONE;
5201     }
5202   else if (TARGET_FCFID)
5203     {
5204       rtx dreg = operands[1];
5205       if (!REG_P (dreg))
5206         dreg = force_reg (SImode, dreg);
5207       dreg = convert_to_mode (DImode, dreg, true);
5208       emit_insn (gen_floatdidf2 (operands[0], dreg));
5209       DONE;
5210     }
5212   if (!REG_P (operands[1]))
5213     operands[1] = force_reg (SImode, operands[1]);
5214   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5215   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5216   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5217   operands[5] = gen_reg_rtx (DFmode);
5220 (define_insn_and_split "*floatunssidf2_internal"
5221   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5222         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5223    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5224    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5225    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5226    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5227   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5228    && !(TARGET_FCFID && TARGET_POWERPC64)"
5229   "#"
5230   ""
5231   [(pc)]
5232   "
5234   rtx lowword, highword;
5235   gcc_assert (MEM_P (operands[4]));
5236   highword = adjust_address (operands[4], SImode, 0);
5237   lowword = adjust_address (operands[4], SImode, 4);
5238   if (! WORDS_BIG_ENDIAN)
5239     std::swap (lowword, highword);
5241   emit_move_insn (lowword, operands[1]);
5242   emit_move_insn (highword, operands[2]);
5243   emit_move_insn (operands[5], operands[4]);
5244   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5245   DONE;
5247   [(set_attr "length" "20")
5248    (set_attr "type" "fp")])
5250 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5251 ;; vector registers.  At the moment, QI/HImode are not allowed in floating
5252 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5253 ;; half-word instructions.
5255 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5256   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5257                    (float:FP_ISA3
5258                     (match_operand:QHI 1 "input_operand")))
5259               (clobber (match_scratch:DI 2))
5260               (clobber (match_scratch:DI 3))])]
5261   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5263   if (MEM_P (operands[1]))
5264     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5267 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5268   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5269         (float:FP_ISA3
5270          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5271    (clobber (match_scratch:DI 2 "=wi,v"))
5272    (clobber (match_scratch:DI 3 "=r,X"))]
5273   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5274    && TARGET_UPPER_REGS_DI"
5275   "#"
5276   "&& reload_completed"
5277   [(const_int 0)]
5279   rtx result = operands[0];
5280   rtx input = operands[1];
5281   rtx di = operands[2];
5283   if (!MEM_P (input))
5284     {
5285       rtx tmp = operands[3];
5286       emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5287       emit_move_insn (di, tmp);
5288     }
5289   else
5290     {
5291       machine_mode vmode;
5292       rtx di_vector;
5294       emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5296       if (<MODE>mode == QImode)
5297         vmode = V16QImode;
5298       else if (<MODE>mode == HImode)
5299         vmode = V8HImode;
5300       else
5301         gcc_unreachable ();
5303       di_vector = gen_rtx_REG (vmode, REGNO (di));
5304       emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5305     }
5307   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5308   DONE;
5311 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5312   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5313                    (unsigned_float:FP_ISA3
5314                     (match_operand:QHI 1 "input_operand" "")))
5315               (clobber (match_scratch:DI 2 ""))
5316               (clobber (match_scratch:DI 3 ""))])]
5317   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5319   if (MEM_P (operands[1]))
5320     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5323 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5324   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5325         (unsigned_float:FP_ISA3
5326          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5327    (clobber (match_scratch:DI 2 "=wi,wi"))
5328    (clobber (match_scratch:DI 3 "=r,X"))]
5329   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5330   "#"
5331   "&& reload_completed"
5332   [(const_int 0)]
5334   rtx result = operands[0];
5335   rtx input = operands[1];
5336   rtx di = operands[2];
5337   rtx tmp = operands[3];
5339   if (!MEM_P (input))
5340     {
5341       emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5342       emit_move_insn (di, tmp);
5343     }
5344   else
5345     emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5347   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5348   DONE;
5351 (define_expand "fix_trunc<mode>si2"
5352   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5353         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5354   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5355   "
5357   if (!<E500_CONVERT>)
5358     {
5359       rtx tmp, stack;
5361       if (TARGET_STFIWX)
5362         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5363       else
5364         {
5365           tmp = gen_reg_rtx (DImode);
5366           stack = rs6000_allocate_stack_temp (DImode, true, false);
5367           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5368                                                       tmp, stack));
5369         }
5370       DONE;
5371     }
5374 ; Like the convert to float patterns, this insn must be split before
5375 ; register allocation so that it can allocate the memory slot if it
5376 ; needed
5377 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5378   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5379         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5380    (clobber (match_scratch:DI 2 "=d"))]
5381   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5382    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5383    && TARGET_STFIWX && can_create_pseudo_p ()"
5384   "#"
5385   ""
5386   [(pc)]
5388   rtx dest = operands[0];
5389   rtx src = operands[1];
5390   rtx tmp = operands[2];
5392   if (GET_CODE (tmp) == SCRATCH)
5393     tmp = gen_reg_rtx (DImode);
5395   emit_insn (gen_fctiwz_<mode> (tmp, src));
5396   if (MEM_P (dest))
5397     {
5398       dest = rs6000_address_for_fpconvert (dest);
5399       emit_insn (gen_stfiwx (dest, tmp));
5400       DONE;
5401     }
5402   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5403     {
5404       dest = gen_lowpart (DImode, dest);
5405       emit_move_insn (dest, tmp);
5406       DONE;
5407     }
5408   else
5409     {
5410       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5411       emit_insn (gen_stfiwx (stack, tmp));
5412       emit_move_insn (dest, stack);
5413       DONE;
5414     }
5416   [(set_attr "length" "12")
5417    (set_attr "type" "fp")])
5419 (define_insn_and_split "fix_trunc<mode>si2_internal"
5420   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5421         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5422    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5423    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5424   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5425   "#"
5426   ""
5427   [(pc)]
5428   "
5430   rtx lowword;
5431   gcc_assert (MEM_P (operands[3]));
5432   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5434   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5435   emit_move_insn (operands[3], operands[2]);
5436   emit_move_insn (operands[0], lowword);
5437   DONE;
5439   [(set_attr "length" "16")
5440    (set_attr "type" "fp")])
5442 (define_expand "fix_trunc<mode>di2"
5443   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5444         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5445   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5446    && TARGET_FCFID"
5447   "")
5449 (define_insn "*fix_trunc<mode>di2_fctidz"
5450   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5451         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5452   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5453     && TARGET_FCFID"
5454   "@
5455    fctidz %0,%1
5456    xscvdpsxds %x0,%x1"
5457   [(set_attr "type" "fp")])
5459 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5460   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5461    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5462   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5464   rtx op0 = operands[0];
5465   rtx op1 = operands[1];
5466   rtx di_tmp = gen_reg_rtx (DImode);
5468   if (MEM_P (op0))
5469     op0 = rs6000_address_for_fpconvert (op0);
5471   emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5472   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5473   DONE;
5476 (define_expand "fixuns_trunc<mode>si2"
5477   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5478         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5479   "TARGET_HARD_FLOAT
5480    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5481        || <E500_CONVERT>)"
5482   "
5484   if (!<E500_CONVERT>)
5485     {
5486       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5487       DONE;
5488     }
5491 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5492   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5493         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5494    (clobber (match_scratch:DI 2 "=d"))]
5495   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5496    && TARGET_STFIWX && can_create_pseudo_p ()"
5497   "#"
5498   ""
5499   [(pc)]
5501   rtx dest = operands[0];
5502   rtx src = operands[1];
5503   rtx tmp = operands[2];
5505   if (GET_CODE (tmp) == SCRATCH)
5506     tmp = gen_reg_rtx (DImode);
5508   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5509   if (MEM_P (dest))
5510     {
5511       dest = rs6000_address_for_fpconvert (dest);
5512       emit_insn (gen_stfiwx (dest, tmp));
5513       DONE;
5514     }
5515   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5516     {
5517       dest = gen_lowpart (DImode, dest);
5518       emit_move_insn (dest, tmp);
5519       DONE;
5520     }
5521   else
5522     {
5523       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5524       emit_insn (gen_stfiwx (stack, tmp));
5525       emit_move_insn (dest, stack);
5526       DONE;
5527     }
5529   [(set_attr "length" "12")
5530    (set_attr "type" "fp")])
5532 (define_expand "fixuns_trunc<mode>di2"
5533   [(set (match_operand:DI 0 "register_operand" "")
5534         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5535   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5536   "")
5538 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5539   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5540         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5541   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5542     && TARGET_FCTIDUZ"
5543   "@
5544    fctiduz %0,%1
5545    xscvdpuxds %x0,%x1"
5546   [(set_attr "type" "fp")])
5548 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5549   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5550    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5551   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5553   rtx op0 = operands[0];
5554   rtx op1 = operands[1];
5555   rtx di_tmp = gen_reg_rtx (DImode);
5557   if (MEM_P (op0))
5558     op0 = rs6000_address_for_fpconvert (op0);
5560   emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5561   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5562   DONE;
5565 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5566 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5567 ; because the first makes it clear that operand 0 is not live
5568 ; before the instruction.
5569 (define_insn "fctiwz_<mode>"
5570   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5571         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5572                    UNSPEC_FCTIWZ))]
5573   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5574   "@
5575    fctiwz %0,%1
5576    xscvdpsxws %x0,%x1"
5577   [(set_attr "type" "fp")])
5579 (define_insn "fctiwuz_<mode>"
5580   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5581         (unspec:DI [(unsigned_fix:SI
5582                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5583                    UNSPEC_FCTIWUZ))]
5584   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5585   "@
5586    fctiwuz %0,%1
5587    xscvdpuxws %x0,%x1"
5588   [(set_attr "type" "fp")])
5590 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5591 ;; since the friz instruction does not truncate the value if the floating
5592 ;; point value is < LONG_MIN or > LONG_MAX.
5593 (define_insn "*friz"
5594   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5595         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5596   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5597    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5598   "@
5599    friz %0,%1
5600    xsrdpiz %x0,%x1"
5601   [(set_attr "type" "fp")])
5603 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5604 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5605 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5606 ;; extend it, store it back on the stack from the GPR, load it back into the
5607 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5608 ;; disable using store and load to sign/zero extend the value.
5609 (define_insn_and_split "*round32<mode>2_fprs"
5610   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5611         (float:SFDF
5612          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5613    (clobber (match_scratch:DI 2 "=d"))
5614    (clobber (match_scratch:DI 3 "=d"))]
5615   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5616    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5617    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5618   "#"
5619   ""
5620   [(pc)]
5622   rtx dest = operands[0];
5623   rtx src = operands[1];
5624   rtx tmp1 = operands[2];
5625   rtx tmp2 = operands[3];
5626   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5628   if (GET_CODE (tmp1) == SCRATCH)
5629     tmp1 = gen_reg_rtx (DImode);
5630   if (GET_CODE (tmp2) == SCRATCH)
5631     tmp2 = gen_reg_rtx (DImode);
5633   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5634   emit_insn (gen_stfiwx (stack, tmp1));
5635   emit_insn (gen_lfiwax (tmp2, stack));
5636   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5637   DONE;
5639   [(set_attr "type" "fpload")
5640    (set_attr "length" "16")])
5642 (define_insn_and_split "*roundu32<mode>2_fprs"
5643   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5644         (unsigned_float:SFDF
5645          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5646    (clobber (match_scratch:DI 2 "=d"))
5647    (clobber (match_scratch:DI 3 "=d"))]
5648   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5649    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5650    && can_create_pseudo_p ()"
5651   "#"
5652   ""
5653   [(pc)]
5655   rtx dest = operands[0];
5656   rtx src = operands[1];
5657   rtx tmp1 = operands[2];
5658   rtx tmp2 = operands[3];
5659   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5661   if (GET_CODE (tmp1) == SCRATCH)
5662     tmp1 = gen_reg_rtx (DImode);
5663   if (GET_CODE (tmp2) == SCRATCH)
5664     tmp2 = gen_reg_rtx (DImode);
5666   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5667   emit_insn (gen_stfiwx (stack, tmp1));
5668   emit_insn (gen_lfiwzx (tmp2, stack));
5669   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5670   DONE;
5672   [(set_attr "type" "fpload")
5673    (set_attr "length" "16")])
5675 ;; No VSX equivalent to fctid
5676 (define_insn "lrint<mode>di2"
5677   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5678         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5679                    UNSPEC_FCTID))]
5680   "TARGET_<MODE>_FPR && TARGET_FPRND"
5681   "fctid %0,%1"
5682   [(set_attr "type" "fp")])
5684 (define_insn "btrunc<mode>2"
5685   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5686         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5687                      UNSPEC_FRIZ))]
5688   "TARGET_<MODE>_FPR && TARGET_FPRND"
5689   "@
5690    friz %0,%1
5691    xsrdpiz %x0,%x1"
5692   [(set_attr "type" "fp")
5693    (set_attr "fp_type" "fp_addsub_<Fs>")])
5695 (define_insn "ceil<mode>2"
5696   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5697         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5698                      UNSPEC_FRIP))]
5699   "TARGET_<MODE>_FPR && TARGET_FPRND"
5700   "@
5701    frip %0,%1
5702    xsrdpip %x0,%x1"
5703   [(set_attr "type" "fp")
5704    (set_attr "fp_type" "fp_addsub_<Fs>")])
5706 (define_insn "floor<mode>2"
5707   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5708         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5709                      UNSPEC_FRIM))]
5710   "TARGET_<MODE>_FPR && TARGET_FPRND"
5711   "@
5712    frim %0,%1
5713    xsrdpim %x0,%x1"
5714   [(set_attr "type" "fp")
5715    (set_attr "fp_type" "fp_addsub_<Fs>")])
5717 ;; No VSX equivalent to frin
5718 (define_insn "round<mode>2"
5719   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5720         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5721                      UNSPEC_FRIN))]
5722   "TARGET_<MODE>_FPR && TARGET_FPRND"
5723   "frin %0,%1"
5724   [(set_attr "type" "fp")
5725    (set_attr "fp_type" "fp_addsub_<Fs>")])
5727 (define_insn "*xsrdpi<mode>2"
5728   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5729         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5730                      UNSPEC_XSRDPI))]
5731   "TARGET_<MODE>_FPR && TARGET_VSX"
5732   "xsrdpi %x0,%x1"
5733   [(set_attr "type" "fp")
5734    (set_attr "fp_type" "fp_addsub_<Fs>")])
5736 (define_expand "lround<mode>di2"
5737   [(set (match_dup 2)
5738         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5739                      UNSPEC_XSRDPI))
5740    (set (match_operand:DI 0 "gpc_reg_operand" "")
5741         (unspec:DI [(match_dup 2)]
5742                    UNSPEC_FCTID))]
5743   "TARGET_<MODE>_FPR && TARGET_VSX"
5745   operands[2] = gen_reg_rtx (<MODE>mode);
5748 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5749 (define_insn "stfiwx"
5750   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5751         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wv")]
5752                    UNSPEC_STFIWX))]
5753   "TARGET_PPC_GFXOPT"
5754   "@
5755    stfiwx %1,%y0
5756    stxsiwx %x1,%y0"
5757   [(set_attr "type" "fpstore")])
5759 ;; If we don't have a direct conversion to single precision, don't enable this
5760 ;; conversion for 32-bit without fast math, because we don't have the insn to
5761 ;; generate the fixup swizzle to avoid double rounding problems.
5762 (define_expand "floatsisf2"
5763   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5764         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5765   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5766    && (!TARGET_FPRS
5767        || (TARGET_FPRS
5768            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5769                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5770                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5771   "
5773   if (!TARGET_FPRS)
5774     {
5775       if (!REG_P (operands[1]))
5776         operands[1] = force_reg (SImode, operands[1]);
5777     }
5778   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5779     {
5780       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5781       DONE;
5782     }
5783   else if (TARGET_FCFID && TARGET_LFIWAX)
5784     {
5785       rtx dfreg = gen_reg_rtx (DFmode);
5786       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5787       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5788       DONE;
5789     }
5790   else
5791     {
5792       rtx dreg = operands[1];
5793       if (!REG_P (dreg))
5794         dreg = force_reg (SImode, dreg);
5795       dreg = convert_to_mode (DImode, dreg, false);
5796       emit_insn (gen_floatdisf2 (operands[0], dreg));
5797       DONE;
5798     }
5801 (define_expand "floatdidf2"
5802   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5803         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5804   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5805   "")
5807 (define_insn "*floatdidf2_fpr"
5808   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5809         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5810   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5811   "@
5812    fcfid %0,%1
5813    xscvsxddp %x0,%x1"
5814   [(set_attr "type" "fp")])
5816 ; Allow the combiner to merge source memory operands to the conversion so that
5817 ; the optimizer/register allocator doesn't try to load the value too early in a
5818 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5819 ; hit.  We will split after reload to avoid the trip through the GPRs
5821 (define_insn_and_split "*floatdidf2_mem"
5822   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5823         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5824    (clobber (match_scratch:DI 2 "=d,wi"))]
5825   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5826   "#"
5827   "&& reload_completed"
5828   [(set (match_dup 2) (match_dup 1))
5829    (set (match_dup 0) (float:DF (match_dup 2)))]
5830   ""
5831   [(set_attr "length" "8")
5832    (set_attr "type" "fpload")])
5834 (define_expand "floatunsdidf2"
5835   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5836         (unsigned_float:DF
5837          (match_operand:DI 1 "gpc_reg_operand" "")))]
5838   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5839   "")
5841 (define_insn "*floatunsdidf2_fcfidu"
5842   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5843         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5844   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5845   "@
5846    fcfidu %0,%1
5847    xscvuxddp %x0,%x1"
5848   [(set_attr "type" "fp")
5849    (set_attr "length" "4")])
5851 (define_insn_and_split "*floatunsdidf2_mem"
5852   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5853         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5854    (clobber (match_scratch:DI 2 "=d,wi"))]
5855   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5856   "#"
5857   "&& reload_completed"
5858   [(set (match_dup 2) (match_dup 1))
5859    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5860   ""
5861   [(set_attr "length" "8")
5862    (set_attr "type" "fpload")])
5864 (define_expand "floatdisf2"
5865   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5866         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5867   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5868    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5869   "
5871   if (!TARGET_FCFIDS)
5872     {
5873       rtx val = operands[1];
5874       if (!flag_unsafe_math_optimizations)
5875         {
5876           rtx label = gen_label_rtx ();
5877           val = gen_reg_rtx (DImode);
5878           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5879           emit_label (label);
5880         }
5881       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5882       DONE;
5883     }
5886 (define_insn "floatdisf2_fcfids"
5887   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5888         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5889   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5890    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5891   "@
5892    fcfids %0,%1
5893    xscvsxdsp %x0,%x1"
5894   [(set_attr "type" "fp")])
5896 (define_insn_and_split "*floatdisf2_mem"
5897   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5898         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5899    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5900   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5901    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5902   "#"
5903   "&& reload_completed"
5904   [(pc)]
5905   "
5907   emit_move_insn (operands[2], operands[1]);
5908   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5909   DONE;
5911   [(set_attr "length" "8")])
5913 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5914 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5915 ;; from double rounding.
5916 ;; Instead of creating a new cpu type for two FP operations, just use fp
5917 (define_insn_and_split "floatdisf2_internal1"
5918   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5919         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5920    (clobber (match_scratch:DF 2 "=d"))]
5921   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5922    && !TARGET_FCFIDS"
5923   "#"
5924   "&& reload_completed"
5925   [(set (match_dup 2)
5926         (float:DF (match_dup 1)))
5927    (set (match_dup 0)
5928         (float_truncate:SF (match_dup 2)))]
5929   ""
5930   [(set_attr "length" "8")
5931    (set_attr "type" "fp")])
5933 ;; Twiddles bits to avoid double rounding.
5934 ;; Bits that might be truncated when converting to DFmode are replaced
5935 ;; by a bit that won't be lost at that stage, but is below the SFmode
5936 ;; rounding position.
5937 (define_expand "floatdisf2_internal2"
5938   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5939                                               (const_int 53)))
5940               (clobber (reg:DI CA_REGNO))])
5941    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5942                                            (const_int 2047)))
5943    (set (match_dup 3) (plus:DI (match_dup 3)
5944                                (const_int 1)))
5945    (set (match_dup 0) (plus:DI (match_dup 0)
5946                                (const_int 2047)))
5947    (set (match_dup 4) (compare:CCUNS (match_dup 3)
5948                                      (const_int 2)))
5949    (set (match_dup 0) (ior:DI (match_dup 0)
5950                               (match_dup 1)))
5951    (set (match_dup 0) (and:DI (match_dup 0)
5952                               (const_int -2048)))
5953    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5954                            (label_ref (match_operand:DI 2 "" ""))
5955                            (pc)))
5956    (set (match_dup 0) (match_dup 1))]
5957   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5958    && !TARGET_FCFIDS"
5959   "
5961   operands[3] = gen_reg_rtx (DImode);
5962   operands[4] = gen_reg_rtx (CCUNSmode);
5965 (define_expand "floatunsdisf2"
5966   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5967         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5968   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5969    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5970   "")
5972 (define_insn "floatunsdisf2_fcfidus"
5973   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5974         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5975   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5976    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5977   "@
5978    fcfidus %0,%1
5979    xscvuxdsp %x0,%x1"
5980   [(set_attr "type" "fp")])
5982 (define_insn_and_split "*floatunsdisf2_mem"
5983   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5984         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5985    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5986   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5987    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5988   "#"
5989   "&& reload_completed"
5990   [(pc)]
5991   "
5993   emit_move_insn (operands[2], operands[1]);
5994   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5995   DONE;
5997   [(set_attr "length" "8")
5998    (set_attr "type" "fpload")])
6000 ;; Define the TImode operations that can be done in a small number
6001 ;; of instructions.  The & constraints are to prevent the register
6002 ;; allocator from allocating registers that overlap with the inputs
6003 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6004 ;; also allow for the output being the same as one of the inputs.
6006 (define_expand "addti3"
6007   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6008         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6009                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6010   "TARGET_64BIT"
6012   rtx lo0 = gen_lowpart (DImode, operands[0]);
6013   rtx lo1 = gen_lowpart (DImode, operands[1]);
6014   rtx lo2 = gen_lowpart (DImode, operands[2]);
6015   rtx hi0 = gen_highpart (DImode, operands[0]);
6016   rtx hi1 = gen_highpart (DImode, operands[1]);
6017   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6019   if (!reg_or_short_operand (lo2, DImode))
6020     lo2 = force_reg (DImode, lo2);
6021   if (!adde_operand (hi2, DImode))
6022     hi2 = force_reg (DImode, hi2);
6024   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6025   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6026   DONE;
6029 (define_expand "subti3"
6030   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6031         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6032                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6033   "TARGET_64BIT"
6035   rtx lo0 = gen_lowpart (DImode, operands[0]);
6036   rtx lo1 = gen_lowpart (DImode, operands[1]);
6037   rtx lo2 = gen_lowpart (DImode, operands[2]);
6038   rtx hi0 = gen_highpart (DImode, operands[0]);
6039   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6040   rtx hi2 = gen_highpart (DImode, operands[2]);
6042   if (!reg_or_short_operand (lo1, DImode))
6043     lo1 = force_reg (DImode, lo1);
6044   if (!adde_operand (hi1, DImode))
6045     hi1 = force_reg (DImode, hi1);
6047   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6048   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6049   DONE;
6052 ;; 128-bit logical operations expanders
6054 (define_expand "and<mode>3"
6055   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6056         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6057                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6058   ""
6059   "")
6061 (define_expand "ior<mode>3"
6062   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6063         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6064                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6065   ""
6066   "")
6068 (define_expand "xor<mode>3"
6069   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6070         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6071                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6072   ""
6073   "")
6075 (define_expand "one_cmpl<mode>2"
6076   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6077         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6078   ""
6079   "")
6081 (define_expand "nor<mode>3"
6082   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6083         (and:BOOL_128
6084          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6085          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6086   ""
6087   "")
6089 (define_expand "andc<mode>3"
6090   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6091         (and:BOOL_128
6092          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6093          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6094   ""
6095   "")
6097 ;; Power8 vector logical instructions.
6098 (define_expand "eqv<mode>3"
6099   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6100         (not:BOOL_128
6101          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6102                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6103   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6104   "")
6106 ;; Rewrite nand into canonical form
6107 (define_expand "nand<mode>3"
6108   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6109         (ior:BOOL_128
6110          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6111          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6112   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6113   "")
6115 ;; The canonical form is to have the negated element first, so we need to
6116 ;; reverse arguments.
6117 (define_expand "orc<mode>3"
6118   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6119         (ior:BOOL_128
6120          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6121          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6122   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6123   "")
6125 ;; 128-bit logical operations insns and split operations
6126 (define_insn_and_split "*and<mode>3_internal"
6127   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6128         (and:BOOL_128
6129          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6130          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6131   ""
6133   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6134     return "xxland %x0,%x1,%x2";
6136   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6137     return "vand %0,%1,%2";
6139   return "#";
6141   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6142   [(const_int 0)]
6144   rs6000_split_logical (operands, AND, false, false, false);
6145   DONE;
6147   [(set (attr "type")
6148       (if_then_else
6149         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6150         (const_string "veclogical")
6151         (const_string "integer")))
6152    (set (attr "length")
6153       (if_then_else
6154         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6155         (const_string "4")
6156         (if_then_else
6157          (match_test "TARGET_POWERPC64")
6158          (const_string "8")
6159          (const_string "16"))))])
6161 ;; 128-bit IOR/XOR
6162 (define_insn_and_split "*bool<mode>3_internal"
6163   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6164         (match_operator:BOOL_128 3 "boolean_or_operator"
6165          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6166           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6167   ""
6169   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6170     return "xxl%q3 %x0,%x1,%x2";
6172   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6173     return "v%q3 %0,%1,%2";
6175   return "#";
6177   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6178   [(const_int 0)]
6180   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6181   DONE;
6183   [(set (attr "type")
6184       (if_then_else
6185         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6186         (const_string "veclogical")
6187         (const_string "integer")))
6188    (set (attr "length")
6189       (if_then_else
6190         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6191         (const_string "4")
6192         (if_then_else
6193          (match_test "TARGET_POWERPC64")
6194          (const_string "8")
6195          (const_string "16"))))])
6197 ;; 128-bit ANDC/ORC
6198 (define_insn_and_split "*boolc<mode>3_internal1"
6199   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6200         (match_operator:BOOL_128 3 "boolean_operator"
6201          [(not:BOOL_128
6202            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6203           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6204   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6206   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6207     return "xxl%q3 %x0,%x1,%x2";
6209   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6210     return "v%q3 %0,%1,%2";
6212   return "#";
6214   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6215    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6216   [(const_int 0)]
6218   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6219   DONE;
6221   [(set (attr "type")
6222       (if_then_else
6223         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6224         (const_string "veclogical")
6225         (const_string "integer")))
6226    (set (attr "length")
6227       (if_then_else
6228         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6229         (const_string "4")
6230         (if_then_else
6231          (match_test "TARGET_POWERPC64")
6232          (const_string "8")
6233          (const_string "16"))))])
6235 (define_insn_and_split "*boolc<mode>3_internal2"
6236   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6237         (match_operator:TI2 3 "boolean_operator"
6238          [(not:TI2
6239            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6240           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6241   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6242   "#"
6243   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6244   [(const_int 0)]
6246   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6247   DONE;
6249   [(set_attr "type" "integer")
6250    (set (attr "length")
6251         (if_then_else
6252          (match_test "TARGET_POWERPC64")
6253          (const_string "8")
6254          (const_string "16")))])
6256 ;; 128-bit NAND/NOR
6257 (define_insn_and_split "*boolcc<mode>3_internal1"
6258   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6259         (match_operator:BOOL_128 3 "boolean_operator"
6260          [(not:BOOL_128
6261            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6262           (not:BOOL_128
6263            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6264   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6266   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6267     return "xxl%q3 %x0,%x1,%x2";
6269   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6270     return "v%q3 %0,%1,%2";
6272   return "#";
6274   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6275    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6276   [(const_int 0)]
6278   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6279   DONE;
6281   [(set (attr "type")
6282       (if_then_else
6283         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6284         (const_string "veclogical")
6285         (const_string "integer")))
6286    (set (attr "length")
6287       (if_then_else
6288         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6289         (const_string "4")
6290         (if_then_else
6291          (match_test "TARGET_POWERPC64")
6292          (const_string "8")
6293          (const_string "16"))))])
6295 (define_insn_and_split "*boolcc<mode>3_internal2"
6296   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6297         (match_operator:TI2 3 "boolean_operator"
6298          [(not:TI2
6299            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6300           (not:TI2
6301            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6302   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6303   "#"
6304   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6305   [(const_int 0)]
6307   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6308   DONE;
6310   [(set_attr "type" "integer")
6311    (set (attr "length")
6312         (if_then_else
6313          (match_test "TARGET_POWERPC64")
6314          (const_string "8")
6315          (const_string "16")))])
6318 ;; 128-bit EQV
6319 (define_insn_and_split "*eqv<mode>3_internal1"
6320   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6321         (not:BOOL_128
6322          (xor:BOOL_128
6323           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6324           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6325   "TARGET_P8_VECTOR"
6327   if (vsx_register_operand (operands[0], <MODE>mode))
6328     return "xxleqv %x0,%x1,%x2";
6330   return "#";
6332   "TARGET_P8_VECTOR && reload_completed
6333    && int_reg_operand (operands[0], <MODE>mode)"
6334   [(const_int 0)]
6336   rs6000_split_logical (operands, XOR, true, false, false);
6337   DONE;
6339   [(set (attr "type")
6340       (if_then_else
6341         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6342         (const_string "veclogical")
6343         (const_string "integer")))
6344    (set (attr "length")
6345       (if_then_else
6346         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6347         (const_string "4")
6348         (if_then_else
6349          (match_test "TARGET_POWERPC64")
6350          (const_string "8")
6351          (const_string "16"))))])
6353 (define_insn_and_split "*eqv<mode>3_internal2"
6354   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6355         (not:TI2
6356          (xor:TI2
6357           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6358           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6359   "!TARGET_P8_VECTOR"
6360   "#"
6361   "reload_completed && !TARGET_P8_VECTOR"
6362   [(const_int 0)]
6364   rs6000_split_logical (operands, XOR, true, false, false);
6365   DONE;
6367   [(set_attr "type" "integer")
6368    (set (attr "length")
6369         (if_then_else
6370          (match_test "TARGET_POWERPC64")
6371          (const_string "8")
6372          (const_string "16")))])
6374 ;; 128-bit one's complement
6375 (define_insn_and_split "*one_cmpl<mode>3_internal"
6376   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6377         (not:BOOL_128
6378           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6379   ""
6381   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6382     return "xxlnor %x0,%x1,%x1";
6384   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6385     return "vnor %0,%1,%1";
6387   return "#";
6389   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6390   [(const_int 0)]
6392   rs6000_split_logical (operands, NOT, false, false, false);
6393   DONE;
6395   [(set (attr "type")
6396       (if_then_else
6397         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6398         (const_string "veclogical")
6399         (const_string "integer")))
6400    (set (attr "length")
6401       (if_then_else
6402         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6403         (const_string "4")
6404         (if_then_else
6405          (match_test "TARGET_POWERPC64")
6406          (const_string "8")
6407          (const_string "16"))))])
6410 ;; Now define ways of moving data around.
6412 ;; Set up a register with a value from the GOT table
6414 (define_expand "movsi_got"
6415   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6416         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6417                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6418   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6419   "
6421   if (GET_CODE (operands[1]) == CONST)
6422     {
6423       rtx offset = const0_rtx;
6424       HOST_WIDE_INT value;
6426       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6427       value = INTVAL (offset);
6428       if (value != 0)
6429         {
6430           rtx tmp = (!can_create_pseudo_p ()
6431                      ? operands[0]
6432                      : gen_reg_rtx (Pmode));
6433           emit_insn (gen_movsi_got (tmp, operands[1]));
6434           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6435           DONE;
6436         }
6437     }
6439   operands[2] = rs6000_got_register (operands[1]);
6442 (define_insn "*movsi_got_internal"
6443   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6444         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6445                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6446                    UNSPEC_MOVSI_GOT))]
6447   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6448   "lwz %0,%a1@got(%2)"
6449   [(set_attr "type" "load")])
6451 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6452 ;; didn't get allocated to a hard register.
6453 (define_split
6454   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6455         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6456                     (match_operand:SI 2 "memory_operand" "")]
6457                    UNSPEC_MOVSI_GOT))]
6458   "DEFAULT_ABI == ABI_V4
6459     && flag_pic == 1
6460     && (reload_in_progress || reload_completed)"
6461   [(set (match_dup 0) (match_dup 2))
6462    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6463                                  UNSPEC_MOVSI_GOT))]
6464   "")
6466 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6467 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6468 ;; and this is even supposed to be faster, but it is simpler not to get
6469 ;; integers in the TOC.
6470 (define_insn "movsi_low"
6471   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6472         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6473                            (match_operand 2 "" ""))))]
6474   "TARGET_MACHO && ! TARGET_64BIT"
6475   "lwz %0,lo16(%2)(%1)"
6476   [(set_attr "type" "load")
6477    (set_attr "length" "4")])
6479 (define_insn "*movsi_internal1"
6480   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6481         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6482   "!TARGET_SINGLE_FPU &&
6483    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6484   "@
6485    mr %0,%1
6486    la %0,%a1
6487    lwz%U1%X1 %0,%1
6488    stw%U0%X0 %1,%0
6489    li %0,%1
6490    lis %0,%v1
6491    #
6492    mf%1 %0
6493    mt%0 %1
6494    mt%0 %1
6495    nop"
6496   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6497    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6499 (define_insn "*movsi_internal1_single"
6500   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6501         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6502   "TARGET_SINGLE_FPU &&
6503    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6504   "@
6505    mr %0,%1
6506    la %0,%a1
6507    lwz%U1%X1 %0,%1
6508    stw%U0%X0 %1,%0
6509    li %0,%1
6510    lis %0,%v1
6511    #
6512    mf%1 %0
6513    mt%0 %1
6514    mt%0 %1
6515    nop
6516    stfs%U0%X0 %1,%0
6517    lfs%U1%X1 %0,%1"
6518   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6519    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6521 ;; Split a load of a large constant into the appropriate two-insn
6522 ;; sequence.
6524 (define_split
6525   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6526         (match_operand:SI 1 "const_int_operand" ""))]
6527   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6528    && (INTVAL (operands[1]) & 0xffff) != 0"
6529   [(set (match_dup 0)
6530         (match_dup 2))
6531    (set (match_dup 0)
6532         (ior:SI (match_dup 0)
6533                 (match_dup 3)))]
6534   "
6536   if (rs6000_emit_set_const (operands[0], operands[1]))
6537     DONE;
6538   else
6539     FAIL;
6542 (define_insn "*mov<mode>_internal2"
6543   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6544         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6545                     (const_int 0)))
6546    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6547   ""
6548   "@
6549    cmp<wd>i %2,%0,0
6550    mr. %0,%1
6551    #"
6552   [(set_attr "type" "cmp,logical,cmp")
6553    (set_attr "dot" "yes")
6554    (set_attr "length" "4,4,8")])
6556 (define_split
6557   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6558         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6559                     (const_int 0)))
6560    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6561   "reload_completed"
6562   [(set (match_dup 0) (match_dup 1))
6563    (set (match_dup 2)
6564         (compare:CC (match_dup 0)
6565                     (const_int 0)))]
6566   "")
6568 (define_insn "*movhi_internal"
6569   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6570         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6571   "gpc_reg_operand (operands[0], HImode)
6572    || gpc_reg_operand (operands[1], HImode)"
6573   "@
6574    mr %0,%1
6575    lhz%U1%X1 %0,%1
6576    sth%U0%X0 %1,%0
6577    li %0,%w1
6578    mf%1 %0
6579    mt%0 %1
6580    nop"
6581   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6583 (define_expand "mov<mode>"
6584   [(set (match_operand:INT 0 "general_operand" "")
6585         (match_operand:INT 1 "any_operand" ""))]
6586   ""
6587   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6589 (define_insn "*movqi_internal"
6590   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6591         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6592   "gpc_reg_operand (operands[0], QImode)
6593    || gpc_reg_operand (operands[1], QImode)"
6594   "@
6595    mr %0,%1
6596    lbz%U1%X1 %0,%1
6597    stb%U0%X0 %1,%0
6598    li %0,%1
6599    mf%1 %0
6600    mt%0 %1
6601    nop"
6602   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6604 ;; Here is how to move condition codes around.  When we store CC data in
6605 ;; an integer register or memory, we store just the high-order 4 bits.
6606 ;; This lets us not shift in the most common case of CR0.
6607 (define_expand "movcc"
6608   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6609         (match_operand:CC 1 "nonimmediate_operand" ""))]
6610   ""
6611   "")
6613 (define_insn "*movcc_internal1"
6614   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6615         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6616   "register_operand (operands[0], CCmode)
6617    || register_operand (operands[1], CCmode)"
6618   "@
6619    mcrf %0,%1
6620    mtcrf 128,%1
6621    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6622    crxor %0,%0,%0
6623    mfcr %0%Q1
6624    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6625    mr %0,%1
6626    li %0,%1
6627    mf%1 %0
6628    mt%0 %1
6629    lwz%U1%X1 %0,%1
6630    stw%U0%X0 %1,%0"
6631   [(set (attr "type")
6632      (cond [(eq_attr "alternative" "0,3")
6633                 (const_string "cr_logical")
6634             (eq_attr "alternative" "1,2")
6635                 (const_string "mtcr")
6636             (eq_attr "alternative" "6,7")
6637                 (const_string "integer")
6638             (eq_attr "alternative" "8")
6639                 (const_string "mfjmpr")
6640             (eq_attr "alternative" "9")
6641                 (const_string "mtjmpr")
6642             (eq_attr "alternative" "10")
6643                 (const_string "load")
6644             (eq_attr "alternative" "11")
6645                 (const_string "store")
6646             (match_test "TARGET_MFCRF")
6647                 (const_string "mfcrf")
6648            ]
6649         (const_string "mfcr")))
6650    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6652 ;; For floating-point, we normally deal with the floating-point registers
6653 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6654 ;; can produce floating-point values in fixed-point registers.  Unless the
6655 ;; value is a simple constant or already in memory, we deal with this by
6656 ;; allocating memory and copying the value explicitly via that memory location.
6658 ;; Move 32-bit binary/decimal floating point
6659 (define_expand "mov<mode>"
6660   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6661         (match_operand:FMOVE32 1 "any_operand" ""))]
6662   "<fmove_ok>"
6663   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6665 (define_split
6666   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6667         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6668   "reload_completed
6669    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6670        || (GET_CODE (operands[0]) == SUBREG
6671            && GET_CODE (SUBREG_REG (operands[0])) == REG
6672            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6673   [(set (match_dup 2) (match_dup 3))]
6674   "
6676   long l;
6678   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6680   if (! TARGET_POWERPC64)
6681     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6682   else
6683     operands[2] = gen_lowpart (SImode, operands[0]);
6685   operands[3] = gen_int_mode (l, SImode);
6688 (define_insn "mov<mode>_hardfloat"
6689   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6690         (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,<zero_fp>,<zero_fp>,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6691   "(gpc_reg_operand (operands[0], <MODE>mode)
6692    || gpc_reg_operand (operands[1], <MODE>mode))
6693    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6694   "@
6695    mr %0,%1
6696    lwz%U1%X1 %0,%1
6697    stw%U0%X0 %1,%0
6698    fmr %0,%1
6699    xscpsgndp %x0,%x1,%x1
6700    xxlxor %x0,%x0,%x0
6701    li %0,0
6702    <f32_li>
6703    <f32_li2>
6704    <f32_si>
6705    <f32_si2>
6706    <f32_lv>
6707    <f32_sv>
6708    mtvsrwz %x0,%1
6709    mfvsrwz %0,%x1
6710    mt%0 %1
6711    mf%1 %0
6712    nop"
6713   [(set_attr "type" "*,load,store,fpsimple,fpsimple,veclogical,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
6714    (set_attr "length" "4")])
6716 (define_insn "*mov<mode>_softfloat"
6717   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6718         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6719   "(gpc_reg_operand (operands[0], <MODE>mode)
6720    || gpc_reg_operand (operands[1], <MODE>mode))
6721    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6722   "@
6723    mr %0,%1
6724    mt%0 %1
6725    mf%1 %0
6726    lwz%U1%X1 %0,%1
6727    stw%U0%X0 %1,%0
6728    li %0,%1
6729    lis %0,%v1
6730    #
6731    #
6732    nop"
6733   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6734    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6737 ;; Move 64-bit binary/decimal floating point
6738 (define_expand "mov<mode>"
6739   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6740         (match_operand:FMOVE64 1 "any_operand" ""))]
6741   ""
6742   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6744 (define_split
6745   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6746         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6747   "! TARGET_POWERPC64 && reload_completed
6748    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6749        || (GET_CODE (operands[0]) == SUBREG
6750            && GET_CODE (SUBREG_REG (operands[0])) == REG
6751            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6752   [(set (match_dup 2) (match_dup 4))
6753    (set (match_dup 3) (match_dup 1))]
6754   "
6756   int endian = (WORDS_BIG_ENDIAN == 0);
6757   HOST_WIDE_INT value = INTVAL (operands[1]);
6759   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6760   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6761   operands[4] = GEN_INT (value >> 32);
6762   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6765 (define_split
6766   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6767         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6768   "! TARGET_POWERPC64 && reload_completed
6769    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6770        || (GET_CODE (operands[0]) == SUBREG
6771            && GET_CODE (SUBREG_REG (operands[0])) == REG
6772            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6773   [(set (match_dup 2) (match_dup 4))
6774    (set (match_dup 3) (match_dup 5))]
6775   "
6777   int endian = (WORDS_BIG_ENDIAN == 0);
6778   long l[2];
6780   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6782   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6783   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6784   operands[4] = gen_int_mode (l[endian], SImode);
6785   operands[5] = gen_int_mode (l[1 - endian], SImode);
6788 (define_split
6789   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6790         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6791   "TARGET_POWERPC64 && reload_completed
6792    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6793        || (GET_CODE (operands[0]) == SUBREG
6794            && GET_CODE (SUBREG_REG (operands[0])) == REG
6795            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6796   [(set (match_dup 2) (match_dup 3))]
6797   "
6799   int endian = (WORDS_BIG_ENDIAN == 0);
6800   long l[2];
6801   HOST_WIDE_INT val;
6803   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6805   operands[2] = gen_lowpart (DImode, operands[0]);
6806   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6807   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6808          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6810   operands[3] = gen_int_mode (val, DImode);
6813 ;; Don't have reload use general registers to load a constant.  It is
6814 ;; less efficient than loading the constant into an FP register, since
6815 ;; it will probably be used there.
6817 ;; The move constraints are ordered to prefer floating point registers before
6818 ;; general purpose registers to avoid doing a store and a load to get the value
6819 ;; into a floating point register when it is needed for a floating point
6820 ;; operation.  Prefer traditional floating point registers over VSX registers,
6821 ;; since the D-form version of the memory instructions does not need a GPR for
6822 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6823 ;; registers.
6825 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6826 ;; except for 0.0 which can be created on VSX with an xor instruction.
6828 (define_insn "*mov<mode>_hardfloat32"
6829   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6830         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6831   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6832    && (gpc_reg_operand (operands[0], <MODE>mode)
6833        || gpc_reg_operand (operands[1], <MODE>mode))"
6834   "@
6835    stfd%U0%X0 %1,%0
6836    lfd%U1%X1 %0,%1
6837    fmr %0,%1
6838    lxsd%U1x %x0,%y1
6839    stxsd%U0x %x1,%y0
6840    lxsd %0,%1
6841    stxsd %1,%0
6842    xxlor %x0,%x1,%x1
6843    xxlxor %x0,%x0,%x0
6844    #
6845    #
6846    #
6847    #"
6848   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6849    (set_attr "size" "64")
6850    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6852 (define_insn "*mov<mode>_softfloat32"
6853   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6854         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6855   "! TARGET_POWERPC64 
6856    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6857        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6858        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6859    && (gpc_reg_operand (operands[0], <MODE>mode)
6860        || gpc_reg_operand (operands[1], <MODE>mode))"
6861   "#"
6862   [(set_attr "type" "store,load,two,*,*,*")
6863    (set_attr "length" "8,8,8,8,12,16")])
6865 ; ld/std require word-aligned displacements -> 'Y' constraint.
6866 ; List Y->r and r->Y before r->r for reload.
6867 (define_insn "*mov<mode>_hardfloat64"
6868   [(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>")
6869         (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"))]
6870   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6871    && (gpc_reg_operand (operands[0], <MODE>mode)
6872        || gpc_reg_operand (operands[1], <MODE>mode))"
6873   "@
6874    stfd%U0%X0 %1,%0
6875    lfd%U1%X1 %0,%1
6876    fmr %0,%1
6877    lxsd %0,%1
6878    stxsd %1,%0
6879    lxsd%U1x %x0,%y1
6880    stxsd%U0x %x1,%y0
6881    xxlor %x0,%x1,%x1
6882    xxlxor %x0,%x0,%x0
6883    li %0,0
6884    std%U0%X0 %1,%0
6885    ld%U1%X1 %0,%1
6886    mr %0,%1
6887    mt%0 %1
6888    mf%1 %0
6889    nop
6890    mftgpr %0,%1
6891    mffgpr %0,%1
6892    mfvsrd %0,%x1
6893    mtvsrd %x0,%1"
6894   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6895    (set_attr "size" "64")
6896    (set_attr "length" "4")])
6898 (define_insn "*mov<mode>_softfloat64"
6899   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6900         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6901   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6902    && (gpc_reg_operand (operands[0], <MODE>mode)
6903        || gpc_reg_operand (operands[1], <MODE>mode))"
6904   "@
6905    std%U0%X0 %1,%0
6906    ld%U1%X1 %0,%1
6907    mr %0,%1
6908    mt%0 %1
6909    mf%1 %0
6910    #
6911    #
6912    #
6913    nop"
6914   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6915    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6917 (define_expand "mov<mode>"
6918   [(set (match_operand:FMOVE128 0 "general_operand" "")
6919         (match_operand:FMOVE128 1 "any_operand" ""))]
6920   ""
6921   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6923 ;; It's important to list Y->r and r->Y before r->r because otherwise
6924 ;; reload, given m->r, will try to pick r->r and reload it, which
6925 ;; doesn't make progress.
6927 ;; We can't split little endian direct moves of TDmode, because the words are
6928 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6929 ;; problematical.  Don't allow direct move for this case.
6931 (define_insn_and_split "*mov<mode>_64bit_dm"
6932   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6933         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6934   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6935    && FLOAT128_2REG_P (<MODE>mode)
6936    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6937    && (gpc_reg_operand (operands[0], <MODE>mode)
6938        || gpc_reg_operand (operands[1], <MODE>mode))"
6939   "#"
6940   "&& reload_completed"
6941   [(pc)]
6942 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6943   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6945 (define_insn_and_split "*movtd_64bit_nodm"
6946   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6947         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6948   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6949    && (gpc_reg_operand (operands[0], TDmode)
6950        || gpc_reg_operand (operands[1], TDmode))"
6951   "#"
6952   "&& reload_completed"
6953   [(pc)]
6954 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6955   [(set_attr "length" "8,8,8,12,12,8")])
6957 (define_insn_and_split "*mov<mode>_32bit"
6958   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
6959         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
6960   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6961    && (FLOAT128_2REG_P (<MODE>mode)
6962        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6963        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6964    && (gpc_reg_operand (operands[0], <MODE>mode)
6965        || gpc_reg_operand (operands[1], <MODE>mode))"
6966   "#"
6967   "&& reload_completed"
6968   [(pc)]
6969 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6970   [(set_attr "length" "8,8,8,8,20,20,16")])
6972 (define_insn_and_split "*mov<mode>_softfloat"
6973   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6974         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6975   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6976    && (gpc_reg_operand (operands[0], <MODE>mode)
6977        || gpc_reg_operand (operands[1], <MODE>mode))"
6978   "#"
6979   "&& reload_completed"
6980   [(pc)]
6981 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6982   [(set_attr "length" "20,20,16")])
6984 (define_expand "extenddf<mode>2"
6985   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6986         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6987   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6988    && TARGET_LONG_DOUBLE_128"
6990   if (FLOAT128_IEEE_P (<MODE>mode))
6991     rs6000_expand_float128_convert (operands[0], operands[1], false);
6992   else if (TARGET_E500_DOUBLE)
6993     {
6994       gcc_assert (<MODE>mode == TFmode);
6995       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6996     }
6997   else if (TARGET_VSX)
6998     {
6999       if (<MODE>mode == TFmode)
7000         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7001       else if (<MODE>mode == IFmode)
7002         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7003       else
7004         gcc_unreachable ();
7005     }
7006    else
7007     {
7008       rtx zero = gen_reg_rtx (DFmode);
7009       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7011       if (<MODE>mode == TFmode)
7012         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7013       else if (<MODE>mode == IFmode)
7014         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7015       else
7016         gcc_unreachable ();
7017     }
7018   DONE;
7021 ;; Allow memory operands for the source to be created by the combiner.
7022 (define_insn_and_split "extenddf<mode>2_fprs"
7023   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7024         (float_extend:IBM128
7025          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7026    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7027   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7028    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7029   "#"
7030   "&& reload_completed"
7031   [(set (match_dup 3) (match_dup 1))
7032    (set (match_dup 4) (match_dup 2))]
7034   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7035   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7037   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7038   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7041 (define_insn_and_split "extenddf<mode>2_vsx"
7042   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7043         (float_extend:IBM128
7044          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7045   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7046   "#"
7047   "&& reload_completed"
7048   [(set (match_dup 2) (match_dup 1))
7049    (set (match_dup 3) (match_dup 4))]
7051   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7052   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7054   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7055   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7056   operands[4] = CONST0_RTX (DFmode);
7059 (define_expand "extendsf<mode>2"
7060   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7061         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7062   "TARGET_HARD_FLOAT
7063    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7064    && TARGET_LONG_DOUBLE_128"
7066   if (FLOAT128_IEEE_P (<MODE>mode))
7067     rs6000_expand_float128_convert (operands[0], operands[1], false);
7068   else
7069     {
7070       rtx tmp = gen_reg_rtx (DFmode);
7071       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7072       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7073     }
7074   DONE;
7077 (define_expand "trunc<mode>df2"
7078   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7079         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7080   "TARGET_HARD_FLOAT
7081    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7082    && TARGET_LONG_DOUBLE_128"
7084   if (FLOAT128_IEEE_P (<MODE>mode))
7085     {
7086       rs6000_expand_float128_convert (operands[0], operands[1], false);
7087       DONE;
7088     }
7091 (define_insn_and_split "trunc<mode>df2_internal1"
7092   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7093         (float_truncate:DF
7094          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7095   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7096    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7097   "@
7098    #
7099    fmr %0,%1"
7100   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7101   [(const_int 0)]
7103   emit_note (NOTE_INSN_DELETED);
7104   DONE;
7106   [(set_attr "type" "fpsimple")])
7108 (define_insn "trunc<mode>df2_internal2"
7109   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7110         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7111   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7112    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7113   "fadd %0,%1,%L1"
7114   [(set_attr "type" "fp")
7115    (set_attr "fp_type" "fp_addsub_d")])
7117 (define_expand "trunc<mode>sf2"
7118   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7119         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7120   "TARGET_HARD_FLOAT
7121    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7122    && TARGET_LONG_DOUBLE_128"
7124   if (FLOAT128_IEEE_P (<MODE>mode))
7125     rs6000_expand_float128_convert (operands[0], operands[1], false);
7126   else if (TARGET_E500_DOUBLE)
7127     {
7128       gcc_assert (<MODE>mode == TFmode);
7129       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7130     }
7131   else if (<MODE>mode == TFmode)
7132     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7133   else if (<MODE>mode == IFmode)
7134     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7135   else
7136     gcc_unreachable ();
7137   DONE;
7140 (define_insn_and_split "trunc<mode>sf2_fprs"
7141   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7142         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7143    (clobber (match_scratch:DF 2 "=d"))]
7144   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7145    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7146   "#"
7147   "&& reload_completed"
7148   [(set (match_dup 2)
7149         (float_truncate:DF (match_dup 1)))
7150    (set (match_dup 0)
7151         (float_truncate:SF (match_dup 2)))]
7152   "")
7154 (define_expand "floatsi<mode>2"
7155   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7156         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7157   "TARGET_HARD_FLOAT
7158    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7159    && TARGET_LONG_DOUBLE_128"
7161   if (FLOAT128_IEEE_P (<MODE>mode))
7162     rs6000_expand_float128_convert (operands[0], operands[1], false);
7163   else
7164     {
7165       rtx tmp = gen_reg_rtx (DFmode);
7166       expand_float (tmp, operands[1], false);
7167       if (<MODE>mode == TFmode)
7168         emit_insn (gen_extenddftf2 (operands[0], tmp));
7169       else if (<MODE>mode == IFmode)
7170         emit_insn (gen_extenddfif2 (operands[0], tmp));
7171       else
7172         gcc_unreachable ();
7173     }
7174   DONE;
7177 ; fadd, but rounding towards zero.
7178 ; This is probably not the optimal code sequence.
7179 (define_insn "fix_trunc_helper<mode>"
7180   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7181         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7182                    UNSPEC_FIX_TRUNC_TF))
7183    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7184   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7185    && FLOAT128_IBM_P (<MODE>mode)"
7186   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7187   [(set_attr "type" "fp")
7188    (set_attr "length" "20")])
7190 (define_expand "fix_trunc<mode>si2"
7191   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7192         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7193   "TARGET_HARD_FLOAT
7194    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7196   if (FLOAT128_IEEE_P (<MODE>mode))
7197     rs6000_expand_float128_convert (operands[0], operands[1], false);
7198   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7199     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7200   else if (<MODE>mode == TFmode)
7201     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7202   else if (<MODE>mode == IFmode)
7203     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7204   else
7205     gcc_unreachable ();
7206   DONE;
7209 (define_expand "fix_trunc<mode>si2_fprs"
7210   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7211                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7212               (clobber (match_dup 2))
7213               (clobber (match_dup 3))
7214               (clobber (match_dup 4))
7215               (clobber (match_dup 5))])]
7216   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7218   operands[2] = gen_reg_rtx (DFmode);
7219   operands[3] = gen_reg_rtx (DFmode);
7220   operands[4] = gen_reg_rtx (DImode);
7221   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7224 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7225   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7226         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7227    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7228    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7229    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7230    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7231   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7232   "#"
7233   ""
7234   [(pc)]
7236   rtx lowword;
7237   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7238                                          operands[3]));
7240   gcc_assert (MEM_P (operands[5]));
7241   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7243   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7244   emit_move_insn (operands[5], operands[4]);
7245   emit_move_insn (operands[0], lowword);
7246   DONE;
7249 (define_expand "fix_trunc<mode>di2"
7250   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7251         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7252   "TARGET_FLOAT128"
7254   rs6000_expand_float128_convert (operands[0], operands[1], false);
7255   DONE;
7258 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7259   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7260         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7261   "TARGET_FLOAT128"
7263   rs6000_expand_float128_convert (operands[0], operands[1], true);
7264   DONE;
7267 (define_expand "floatdi<mode>2"
7268   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7269         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7270   "TARGET_FLOAT128"
7272   rs6000_expand_float128_convert (operands[0], operands[1], false);
7273   DONE;
7276 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7277   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7278         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7279   "TARGET_FLOAT128"
7281   rs6000_expand_float128_convert (operands[0], operands[1], true);
7282   DONE;
7285 (define_expand "neg<mode>2"
7286   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7287         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7288   "FLOAT128_IEEE_P (<MODE>mode)
7289    || (FLOAT128_IBM_P (<MODE>mode)
7290        && TARGET_HARD_FLOAT
7291        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7292   "
7294   if (FLOAT128_IEEE_P (<MODE>mode))
7295     {
7296       if (TARGET_FLOAT128_HW)
7297         {
7298           if (<MODE>mode == TFmode)
7299             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7300           else if (<MODE>mode == KFmode)
7301             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7302           else
7303             gcc_unreachable ();
7304         }
7305       else if (TARGET_FLOAT128)
7306         {
7307           if (<MODE>mode == TFmode)
7308             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7309           else if (<MODE>mode == KFmode)
7310             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7311           else
7312             gcc_unreachable ();
7313         }
7314       else
7315         {
7316           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7317           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7318                                                 <MODE>mode, 1,
7319                                                 operands[1], <MODE>mode);
7321           if (target && !rtx_equal_p (target, operands[0]))
7322             emit_move_insn (operands[0], target);
7323         }
7324       DONE;
7325     }
7328 (define_insn "neg<mode>2_internal"
7329   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7330         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7331   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7332   "*
7334   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7335     return \"fneg %L0,%L1\;fneg %0,%1\";
7336   else
7337     return \"fneg %0,%1\;fneg %L0,%L1\";
7339   [(set_attr "type" "fpsimple")
7340    (set_attr "length" "8")])
7342 (define_expand "abs<mode>2"
7343   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7344         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7345   "FLOAT128_IEEE_P (<MODE>mode)
7346    || (FLOAT128_IBM_P (<MODE>mode)
7347        && TARGET_HARD_FLOAT
7348        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7349   "
7351   rtx label;
7353   if (FLOAT128_IEEE_P (<MODE>mode))
7354     {
7355       if (TARGET_FLOAT128_HW)
7356         {
7357           if (<MODE>mode == TFmode)
7358             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7359           else if (<MODE>mode == KFmode)
7360             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7361           else
7362             FAIL;
7363           DONE;
7364         }
7365       else if (TARGET_FLOAT128)
7366         {
7367           if (<MODE>mode == TFmode)
7368             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7369           else if (<MODE>mode == KFmode)
7370             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7371           else
7372             FAIL;
7373           DONE;
7374         }
7375       else
7376         FAIL;
7377     }
7379   label = gen_label_rtx ();
7380   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7381     {
7382       if (flag_finite_math_only && !flag_trapping_math)
7383         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7384       else
7385         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7386     }
7387   else if (<MODE>mode == TFmode)
7388     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7389   else if (<MODE>mode == TFmode)
7390     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7391   else
7392     FAIL;
7393   emit_label (label);
7394   DONE;
7397 (define_expand "abs<mode>2_internal"
7398   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7399         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7400    (set (match_dup 3) (match_dup 5))
7401    (set (match_dup 5) (abs:DF (match_dup 5)))
7402    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7403    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7404                            (label_ref (match_operand 2 "" ""))
7405                            (pc)))
7406    (set (match_dup 6) (neg:DF (match_dup 6)))]
7407   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7408    && TARGET_LONG_DOUBLE_128"
7409   "
7411   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7412   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7413   operands[3] = gen_reg_rtx (DFmode);
7414   operands[4] = gen_reg_rtx (CCFPmode);
7415   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7416   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7420 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7421 ;; register
7423 (define_expand "ieee_128bit_negative_zero"
7424   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7425   "TARGET_FLOAT128"
7427   rtvec v = rtvec_alloc (16);
7428   int i, high;
7430   for (i = 0; i < 16; i++)
7431     RTVEC_ELT (v, i) = const0_rtx;
7433   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7434   RTVEC_ELT (v, high) = GEN_INT (0x80);
7436   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7437   DONE;
7440 ;; IEEE 128-bit negate
7442 ;; We have 2 insns here for negate and absolute value.  The first uses
7443 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7444 ;; insns, and second insn after the first split pass loads up the bit to
7445 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7446 ;; neg/abs to create the constant just once.
7448 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7449   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7450         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7451    (clobber (match_scratch:V16QI 2 "=v"))]
7452   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7453   "#"
7454   "&& 1"
7455   [(parallel [(set (match_dup 0)
7456                    (neg:IEEE128 (match_dup 1)))
7457               (use (match_dup 2))])]
7459   if (GET_CODE (operands[2]) == SCRATCH)
7460     operands[2] = gen_reg_rtx (V16QImode);
7462   operands[3] = gen_reg_rtx (V16QImode);
7463   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7465   [(set_attr "length" "8")
7466    (set_attr "type" "vecsimple")])
7468 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7469   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7470         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7471    (use (match_operand:V16QI 2 "register_operand" "v"))]
7472   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7473   "xxlxor %x0,%x1,%x2"
7474   [(set_attr "type" "veclogical")])
7476 ;; IEEE 128-bit absolute value
7477 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7478   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7479         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7480    (clobber (match_scratch:V16QI 2 "=v"))]
7481   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7482   "#"
7483   "&& 1"
7484   [(parallel [(set (match_dup 0)
7485                    (abs:IEEE128 (match_dup 1)))
7486               (use (match_dup 2))])]
7488   if (GET_CODE (operands[2]) == SCRATCH)
7489     operands[2] = gen_reg_rtx (V16QImode);
7491   operands[3] = gen_reg_rtx (V16QImode);
7492   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7494   [(set_attr "length" "8")
7495    (set_attr "type" "vecsimple")])
7497 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7498   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7499         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7500    (use (match_operand:V16QI 2 "register_operand" "v"))]
7501   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7502   "xxlandc %x0,%x1,%x2"
7503   [(set_attr "type" "veclogical")])
7505 ;; IEEE 128-bit negative absolute value
7506 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7507   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7508         (neg:IEEE128
7509          (abs:IEEE128
7510           (match_operand:IEEE128 1 "register_operand" "wa"))))
7511    (clobber (match_scratch:V16QI 2 "=v"))]
7512   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7513   "#"
7514   "&& 1"
7515   [(parallel [(set (match_dup 0)
7516                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7517               (use (match_dup 2))])]
7519   if (GET_CODE (operands[2]) == SCRATCH)
7520     operands[2] = gen_reg_rtx (V16QImode);
7522   operands[3] = gen_reg_rtx (V16QImode);
7523   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7525   [(set_attr "length" "8")
7526    (set_attr "type" "vecsimple")])
7528 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7529   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7530         (neg:IEEE128
7531          (abs:IEEE128
7532           (match_operand:IEEE128 1 "register_operand" "wa"))))
7533    (use (match_operand:V16QI 2 "register_operand" "v"))]
7534   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7535   "xxlor %x0,%x1,%x2"
7536   [(set_attr "type" "veclogical")])
7538 ;; Float128 conversion functions.  These expand to library function calls.
7539 ;; We use expand to convert from IBM double double to IEEE 128-bit
7540 ;; and trunc for the opposite.
7541 (define_expand "extendiftf2"
7542   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7543         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7544   "TARGET_FLOAT128"
7546   rs6000_expand_float128_convert (operands[0], operands[1], false);
7547   DONE;
7550 (define_expand "extendifkf2"
7551   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7552         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7553   "TARGET_FLOAT128"
7555   rs6000_expand_float128_convert (operands[0], operands[1], false);
7556   DONE;
7559 (define_expand "extendtfkf2"
7560   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7561         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7562   "TARGET_FLOAT128"
7564   rs6000_expand_float128_convert (operands[0], operands[1], false);
7565   DONE;
7568 (define_expand "trunciftf2"
7569   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7570         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7571   "TARGET_FLOAT128"
7573   rs6000_expand_float128_convert (operands[0], operands[1], false);
7574   DONE;
7577 (define_expand "truncifkf2"
7578   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7579         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7580   "TARGET_FLOAT128"
7582   rs6000_expand_float128_convert (operands[0], operands[1], false);
7583   DONE;
7586 (define_expand "trunckftf2"
7587   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7588         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7589   "TARGET_FLOAT128"
7591   rs6000_expand_float128_convert (operands[0], operands[1], false);
7592   DONE;
7595 (define_expand "trunctfif2"
7596   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7597         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7598   "TARGET_FLOAT128"
7600   rs6000_expand_float128_convert (operands[0], operands[1], false);
7601   DONE;
7605 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7606 ;; must have 3 arguments, and scratch register constraint must be a single
7607 ;; constraint.
7609 ;; Reload patterns to support gpr load/store with misaligned mem.
7610 ;; and multiple gpr load/store at offset >= 0xfffc
7611 (define_expand "reload_<mode>_store"
7612   [(parallel [(match_operand 0 "memory_operand" "=m")
7613               (match_operand 1 "gpc_reg_operand" "r")
7614               (match_operand:GPR 2 "register_operand" "=&b")])]
7615   ""
7617   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7618   DONE;
7621 (define_expand "reload_<mode>_load"
7622   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7623               (match_operand 1 "memory_operand" "m")
7624               (match_operand:GPR 2 "register_operand" "=b")])]
7625   ""
7627   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7628   DONE;
7632 ;; Reload patterns for various types using the vector registers.  We may need
7633 ;; an additional base register to convert the reg+offset addressing to reg+reg
7634 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7635 ;; index register for gpr registers.
7636 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7637   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7638               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7639               (match_operand:P 2 "register_operand" "=b")])]
7640   "<P:tptrsize>"
7642   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7643   DONE;
7646 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7647   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7648               (match_operand:RELOAD 1 "memory_operand" "m")
7649               (match_operand:P 2 "register_operand" "=b")])]
7650   "<P:tptrsize>"
7652   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7653   DONE;
7657 ;; Reload sometimes tries to move the address to a GPR, and can generate
7658 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7659 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7661 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7662   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7663         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7664                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7665                (const_int -16)))]
7666   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7667   "#"
7668   "&& reload_completed"
7669   [(set (match_dup 0)
7670         (plus:P (match_dup 1)
7671                 (match_dup 2)))
7672    (set (match_dup 0)
7673         (and:P (match_dup 0)
7674                (const_int -16)))])
7676 ;; Power8 merge instructions to allow direct move to/from floating point
7677 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7678 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7679 ;; value, since it is allocated in reload and not all of the flow information
7680 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7681 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7682 ;; schedule other instructions between the two instructions.
7684 (define_insn "p8_fmrgow_<mode>"
7685   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7686         (unspec:FMOVE64X [
7687                 (match_operand:DF 1 "register_operand" "d")
7688                 (match_operand:DF 2 "register_operand" "d")]
7689                          UNSPEC_P8V_FMRGOW))]
7690   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7691   "fmrgow %0,%1,%2"
7692   [(set_attr "type" "fpsimple")])
7694 (define_insn "p8_mtvsrwz"
7695   [(set (match_operand:DF 0 "register_operand" "=d")
7696         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7697                    UNSPEC_P8V_MTVSRWZ))]
7698   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7699   "mtvsrwz %x0,%1"
7700   [(set_attr "type" "mftgpr")])
7702 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7703   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7704         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7705                          UNSPEC_P8V_RELOAD_FROM_GPR))
7706    (clobber (match_operand:IF 2 "register_operand" "=d"))]
7707   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7708   "#"
7709   "&& reload_completed"
7710   [(const_int 0)]
7712   rtx dest = operands[0];
7713   rtx src = operands[1];
7714   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7715   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7716   rtx gpr_hi_reg = gen_highpart (SImode, src);
7717   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7719   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7720   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7721   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7722   DONE;
7724   [(set_attr "length" "12")
7725    (set_attr "type" "three")])
7727 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7728 (define_insn "p8_mtvsrd_df"
7729   [(set (match_operand:DF 0 "register_operand" "=wa")
7730         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7731                    UNSPEC_P8V_MTVSRD))]
7732   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7733   "mtvsrd %x0,%1"
7734   [(set_attr "type" "mftgpr")])
7736 (define_insn "p8_xxpermdi_<mode>"
7737   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7738         (unspec:FMOVE128_GPR [
7739                 (match_operand:DF 1 "register_operand" "wa")
7740                 (match_operand:DF 2 "register_operand" "wa")]
7741                 UNSPEC_P8V_XXPERMDI))]
7742   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7743   "xxpermdi %x0,%x1,%x2,0"
7744   [(set_attr "type" "vecperm")])
7746 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7747   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7748         (unspec:FMOVE128_GPR
7749          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7750          UNSPEC_P8V_RELOAD_FROM_GPR))
7751    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7752   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7753   "#"
7754   "&& reload_completed"
7755   [(const_int 0)]
7757   rtx dest = operands[0];
7758   rtx src = operands[1];
7759   /* You might think that we could use op0 as one temp and a DF clobber
7760      as op2, but you'd be wrong.  Secondary reload move patterns don't
7761      check for overlap of the clobber and the destination.  */
7762   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7763   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7764   rtx gpr_hi_reg = gen_highpart (DImode, src);
7765   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7767   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7768   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7769   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7770   DONE;
7772   [(set_attr "length" "12")
7773    (set_attr "type" "three")])
7775 (define_split
7776   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7777         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7778   "reload_completed
7779    && (int_reg_operand (operands[0], <MODE>mode)
7780        || int_reg_operand (operands[1], <MODE>mode))
7781    && (!TARGET_DIRECT_MOVE_128
7782        || (!vsx_register_operand (operands[0], <MODE>mode)
7783            && !vsx_register_operand (operands[1], <MODE>mode)))"
7784   [(pc)]
7785 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7787 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7788 ;; type is stored internally as double precision in the VSX registers, we have
7789 ;; to convert it from the vector format.
7790 (define_insn "p8_mtvsrd_sf"
7791   [(set (match_operand:SF 0 "register_operand" "=wa")
7792         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7793                    UNSPEC_P8V_MTVSRD))]
7794   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7795   "mtvsrd %x0,%1"
7796   [(set_attr "type" "mftgpr")])
7798 (define_insn_and_split "reload_vsx_from_gprsf"
7799   [(set (match_operand:SF 0 "register_operand" "=wa")
7800         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7801                    UNSPEC_P8V_RELOAD_FROM_GPR))
7802    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7803   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7804   "#"
7805   "&& reload_completed"
7806   [(const_int 0)]
7808   rtx op0 = operands[0];
7809   rtx op1 = operands[1];
7810   rtx op2 = operands[2];
7811   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7813   /* Move SF value to upper 32-bits for xscvspdpn.  */
7814   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7815   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7816   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7817   DONE;
7819   [(set_attr "length" "8")
7820    (set_attr "type" "two")])
7822 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7823 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7824 ;; and then doing a move of that.
7825 (define_insn "p8_mfvsrd_3_<mode>"
7826   [(set (match_operand:DF 0 "register_operand" "=r")
7827         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7828                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7829   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7830   "mfvsrd %0,%x1"
7831   [(set_attr "type" "mftgpr")])
7833 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7834   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7835         (unspec:FMOVE128_GPR
7836          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7837          UNSPEC_P8V_RELOAD_FROM_VSX))
7838    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7839   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7840   "#"
7841   "&& reload_completed"
7842   [(const_int 0)]
7844   rtx dest = operands[0];
7845   rtx src = operands[1];
7846   rtx tmp = operands[2];
7847   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7848   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7850   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7851   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7852   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7853   DONE;
7855   [(set_attr "length" "12")
7856    (set_attr "type" "three")])
7858 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7859 ;; type is stored internally as double precision, we have to convert it to the
7860 ;; vector format.
7862 (define_insn_and_split "reload_gpr_from_vsxsf"
7863   [(set (match_operand:SF 0 "register_operand" "=r")
7864         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7865                    UNSPEC_P8V_RELOAD_FROM_VSX))
7866    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7867   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7868   "#"
7869   "&& reload_completed"
7870   [(const_int 0)]
7872   rtx op0 = operands[0];
7873   rtx op1 = operands[1];
7874   rtx op2 = operands[2];
7875   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7877   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7878   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7879   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7880   DONE;
7882   [(set_attr "length" "12")
7883    (set_attr "type" "three")])
7885 (define_insn "p8_mfvsrd_4_disf"
7886   [(set (match_operand:DI 0 "register_operand" "=r")
7887         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7888                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7889   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7890   "mfvsrd %0,%x1"
7891   [(set_attr "type" "mftgpr")])
7894 ;; Next come the multi-word integer load and store and the load and store
7895 ;; multiple insns.
7897 ;; List r->r after r->Y, otherwise reload will try to reload a
7898 ;; non-offsettable address by using r->r which won't make progress.
7899 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7900 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7902 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
7903 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
7904 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
7905 ;;        AVX const  
7907 (define_insn "*movdi_internal32"
7908   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
7909          "=Y,        r,         r,         ?m,        ?*d,        ?*d,
7910           r,         ?wY,       ?Z,        ?*wb,      ?*wv,       ?wi,
7911           ?wo,       ?wo,       ?wv,       ?wi,       ?wi,        ?wv,
7912           ?wv")
7914         (match_operand:DI 1 "input_operand"
7915           "r,        Y,         r,         d,         m,          d,
7916            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
7917            Oj,       wM,        OjwM,      Oj,        wM,         wS,
7918            wB"))]
7920   "! TARGET_POWERPC64
7921    && (gpc_reg_operand (operands[0], DImode)
7922        || gpc_reg_operand (operands[1], DImode))"
7923   "@
7924    #
7925    #
7926    #
7927    stfd%U0%X0 %1,%0
7928    lfd%U1%X1 %0,%1
7929    fmr %0,%1
7930    #
7931    stxsd %1,%0
7932    stxsdx %x1,%y0
7933    lxsd %0,%1
7934    lxsdx %x0,%y1
7935    xxlor %x0,%x1,%x1
7936    xxspltib %x0,0
7937    xxspltib %x0,255
7938    vspltisw %0,%1
7939    xxlxor %x0,%x0,%x0
7940    xxlorc %x0,%x0,%x0
7941    #
7942    #"
7943   [(set_attr "type"
7944                "store,     load,      *,         fpstore,    fpload,     fpsimple,
7945                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
7946                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
7947                 vecsimple")
7948    (set_attr "size" "64")])
7950 (define_split
7951   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7952         (match_operand:DI 1 "const_int_operand" ""))]
7953   "! TARGET_POWERPC64 && reload_completed
7954    && gpr_or_gpr_p (operands[0], operands[1])
7955    && !direct_move_p (operands[0], operands[1])"
7956   [(set (match_dup 2) (match_dup 4))
7957    (set (match_dup 3) (match_dup 1))]
7958   "
7960   HOST_WIDE_INT value = INTVAL (operands[1]);
7961   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7962                                        DImode);
7963   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7964                                        DImode);
7965   operands[4] = GEN_INT (value >> 32);
7966   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7969 (define_split
7970   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7971         (match_operand:DIFD 1 "input_operand" ""))]
7972   "reload_completed && !TARGET_POWERPC64
7973    && gpr_or_gpr_p (operands[0], operands[1])
7974    && !direct_move_p (operands[0], operands[1])"
7975   [(pc)]
7976 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7978 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
7979 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
7980 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
7981 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
7982 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
7983 (define_insn "*movdi_internal64"
7984   [(set (match_operand:DI 0 "nonimmediate_operand"
7985                "=Y,        r,         r,         r,         r,          r,
7986                 ?m,        ?*d,       ?*d,       ?wY,       ?Z,         ?*wb,
7987                 ?*wv,      ?wi,       ?wo,       ?wo,       ?wv,        ?wi,
7988                 ?wi,       ?wv,       ?wv,       r,         *h,         *h,
7989                 ?*r,       ?*wg,      ?*r,       ?*wj")
7991         (match_operand:DI 1 "input_operand"
7992                 "r,        Y,         r,         I,         L,          nF,
7993                  d,        m,         d,         wb,        wv,         wY,
7994                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
7995                  wM,       wS,        wB,        *h,        r,          0,
7996                  wg,       r,         wj,        r"))]
7998   "TARGET_POWERPC64
7999    && (gpc_reg_operand (operands[0], DImode)
8000        || gpc_reg_operand (operands[1], DImode))"
8001   "@
8002    std%U0%X0 %1,%0
8003    ld%U1%X1 %0,%1
8004    mr %0,%1
8005    li %0,%1
8006    lis %0,%v1
8007    #
8008    stfd%U0%X0 %1,%0
8009    lfd%U1%X1 %0,%1
8010    fmr %0,%1
8011    stxsd %1,%0
8012    stxsdx %x1,%y0
8013    lxsd %0,%1
8014    lxsdx %x0,%y1
8015    xxlor %x0,%x1,%x1
8016    xxspltib %x0,0
8017    xxspltib %x0,255
8018    vspltisw %0,%1
8019    xxlxor %x0,%x0,%x0
8020    xxlorc %x0,%x0,%x0
8021    #
8022    #
8023    mf%1 %0
8024    mt%0 %1
8025    nop
8026    mftgpr %0,%1
8027    mffgpr %0,%1
8028    mfvsrd %0,%x1
8029    mtvsrd %x0,%1"
8030   [(set_attr "type"
8031                "store,      load,       *,         *,         *,         *,
8032                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8033                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8034                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8035                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8037    (set_attr "size" "64")
8038    (set_attr "length"
8039                "4,         4,         4,         4,         4,          20,
8040                 4,         4,         4,         4,         4,          4,
8041                 4,         4,         4,         4,         4,          8,
8042                 8,         4,         4,         4,         4,          4,
8043                 4,         4,         4,         4")])
8045 ; Some DImode loads are best done as a load of -1 followed by a mask
8046 ; instruction.
8047 (define_split
8048   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8049         (match_operand:DI 1 "const_int_operand"))]
8050   "TARGET_POWERPC64
8051    && num_insns_constant (operands[1], DImode) > 1
8052    && rs6000_is_valid_and_mask (operands[1], DImode)"
8053   [(set (match_dup 0)
8054         (const_int -1))
8055    (set (match_dup 0)
8056         (and:DI (match_dup 0)
8057                 (match_dup 1)))]
8058   "")
8060 ;; Split a load of a large constant into the appropriate five-instruction
8061 ;; sequence.  Handle anything in a constant number of insns.
8062 ;; When non-easy constants can go in the TOC, this should use
8063 ;; easy_fp_constant predicate.
8064 (define_split
8065   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8066         (match_operand:DI 1 "const_int_operand" ""))]
8067   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8068   [(set (match_dup 0) (match_dup 2))
8069    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8070   "
8072   if (rs6000_emit_set_const (operands[0], operands[1]))
8073     DONE;
8074   else
8075     FAIL;
8078 (define_split
8079   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8080         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8081   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8082   [(set (match_dup 0) (match_dup 2))
8083    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8084   "
8086   if (rs6000_emit_set_const (operands[0], operands[1]))
8087     DONE;
8088   else
8089     FAIL;
8092 (define_split
8093   [(set (match_operand:DI 0 "altivec_register_operand" "")
8094         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8095   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8096   [(const_int 0)]
8098   rtx op0 = operands[0];
8099   rtx op1 = operands[1];
8100   int r = REGNO (op0);
8101   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8103   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8104   if (op1 != const0_rtx && op1 != constm1_rtx)
8105     {
8106       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8107       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8108     }
8109   DONE;
8112 (define_split
8113   [(set (match_operand:DI 0 "altivec_register_operand" "")
8114         (match_operand:DI 1 "xxspltib_constant_split" ""))]
8115   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8116   [(const_int 0)]
8118   rtx op0 = operands[0];
8119   rtx op1 = operands[1];
8120   int r = REGNO (op0);
8121   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8123   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8124   emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8125   DONE;
8129 ;; TImode/PTImode is similar, except that we usually want to compute the
8130 ;; address into a register and use lsi/stsi (the exception is during reload).
8132 (define_insn "*mov<mode>_string"
8133   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8134         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8135   "! TARGET_POWERPC64
8136    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8137    && (gpc_reg_operand (operands[0], <MODE>mode)
8138        || gpc_reg_operand (operands[1], <MODE>mode))"
8139   "*
8141   switch (which_alternative)
8142     {
8143     default:
8144       gcc_unreachable ();
8145     case 0:
8146       if (TARGET_STRING)
8147         return \"stswi %1,%P0,16\";
8148     case 1:
8149       return \"#\";
8150     case 2:
8151       /* If the address is not used in the output, we can use lsi.  Otherwise,
8152          fall through to generating four loads.  */
8153       if (TARGET_STRING
8154           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8155         return \"lswi %0,%P1,16\";
8156       /* ... fall through ...  */
8157     case 3:
8158     case 4:
8159     case 5:
8160       return \"#\";
8161     }
8163   [(set_attr "type" "store,store,load,load,*,*")
8164    (set_attr "update" "yes")
8165    (set_attr "indexed" "yes")
8166    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8167                                           (const_string "always")
8168                                           (const_string "conditional")))])
8170 (define_insn "*mov<mode>_ppc64"
8171   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8172         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8173   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8174    && (gpc_reg_operand (operands[0], <MODE>mode)
8175        || gpc_reg_operand (operands[1], <MODE>mode)))"
8177   return rs6000_output_move_128bit (operands);
8179   [(set_attr "type" "store,store,load,load,*,*")
8180    (set_attr "length" "8")])
8182 (define_split
8183   [(set (match_operand:TI2 0 "int_reg_operand" "")
8184         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8185   "TARGET_POWERPC64
8186    && (VECTOR_MEM_NONE_P (<MODE>mode)
8187        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8188   [(set (match_dup 2) (match_dup 4))
8189    (set (match_dup 3) (match_dup 5))]
8190   "
8192   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8193                                        <MODE>mode);
8194   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8195                                        <MODE>mode);
8196   if (CONST_WIDE_INT_P (operands[1]))
8197     {
8198       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8199       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8200     }
8201   else if (CONST_INT_P (operands[1]))
8202     {
8203       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8204       operands[5] = operands[1];
8205     }
8206   else
8207     FAIL;
8210 (define_split
8211   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8212         (match_operand:TI2 1 "input_operand" ""))]
8213   "reload_completed
8214    && gpr_or_gpr_p (operands[0], operands[1])
8215    && !direct_move_p (operands[0], operands[1])
8216    && !quad_load_store_p (operands[0], operands[1])"
8217   [(pc)]
8218 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8220 (define_expand "load_multiple"
8221   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8222                           (match_operand:SI 1 "" ""))
8223                      (use (match_operand:SI 2 "" ""))])]
8224   "TARGET_STRING && !TARGET_POWERPC64"
8225   "
8227   int regno;
8228   int count;
8229   rtx op1;
8230   int i;
8232   /* Support only loading a constant number of fixed-point registers from
8233      memory and only bother with this if more than two; the machine
8234      doesn't support more than eight.  */
8235   if (GET_CODE (operands[2]) != CONST_INT
8236       || INTVAL (operands[2]) <= 2
8237       || INTVAL (operands[2]) > 8
8238       || GET_CODE (operands[1]) != MEM
8239       || GET_CODE (operands[0]) != REG
8240       || REGNO (operands[0]) >= 32)
8241     FAIL;
8243   count = INTVAL (operands[2]);
8244   regno = REGNO (operands[0]);
8246   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8247   op1 = replace_equiv_address (operands[1],
8248                                force_reg (SImode, XEXP (operands[1], 0)));
8250   for (i = 0; i < count; i++)
8251     XVECEXP (operands[3], 0, i)
8252       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8253                      adjust_address_nv (op1, SImode, i * 4));
8256 (define_insn "*ldmsi8"
8257   [(match_parallel 0 "load_multiple_operation"
8258     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8259           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8260      (set (match_operand:SI 3 "gpc_reg_operand" "")
8261           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8262      (set (match_operand:SI 4 "gpc_reg_operand" "")
8263           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8264      (set (match_operand:SI 5 "gpc_reg_operand" "")
8265           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8266      (set (match_operand:SI 6 "gpc_reg_operand" "")
8267           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8268      (set (match_operand:SI 7 "gpc_reg_operand" "")
8269           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8270      (set (match_operand:SI 8 "gpc_reg_operand" "")
8271           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8272      (set (match_operand:SI 9 "gpc_reg_operand" "")
8273           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8274   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8275   "*
8276 { return rs6000_output_load_multiple (operands); }"
8277   [(set_attr "type" "load")
8278    (set_attr "update" "yes")
8279    (set_attr "indexed" "yes")
8280    (set_attr "length" "32")])
8282 (define_insn "*ldmsi7"
8283   [(match_parallel 0 "load_multiple_operation"
8284     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8285           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8286      (set (match_operand:SI 3 "gpc_reg_operand" "")
8287           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8288      (set (match_operand:SI 4 "gpc_reg_operand" "")
8289           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8290      (set (match_operand:SI 5 "gpc_reg_operand" "")
8291           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8292      (set (match_operand:SI 6 "gpc_reg_operand" "")
8293           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8294      (set (match_operand:SI 7 "gpc_reg_operand" "")
8295           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8296      (set (match_operand:SI 8 "gpc_reg_operand" "")
8297           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8298   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8299   "*
8300 { return rs6000_output_load_multiple (operands); }"
8301   [(set_attr "type" "load")
8302    (set_attr "update" "yes")
8303    (set_attr "indexed" "yes")
8304    (set_attr "length" "32")])
8306 (define_insn "*ldmsi6"
8307   [(match_parallel 0 "load_multiple_operation"
8308     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8309           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8310      (set (match_operand:SI 3 "gpc_reg_operand" "")
8311           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8312      (set (match_operand:SI 4 "gpc_reg_operand" "")
8313           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8314      (set (match_operand:SI 5 "gpc_reg_operand" "")
8315           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8316      (set (match_operand:SI 6 "gpc_reg_operand" "")
8317           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8318      (set (match_operand:SI 7 "gpc_reg_operand" "")
8319           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8320   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8321   "*
8322 { return rs6000_output_load_multiple (operands); }"
8323   [(set_attr "type" "load")
8324    (set_attr "update" "yes")
8325    (set_attr "indexed" "yes")
8326    (set_attr "length" "32")])
8328 (define_insn "*ldmsi5"
8329   [(match_parallel 0 "load_multiple_operation"
8330     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8331           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8332      (set (match_operand:SI 3 "gpc_reg_operand" "")
8333           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8334      (set (match_operand:SI 4 "gpc_reg_operand" "")
8335           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8336      (set (match_operand:SI 5 "gpc_reg_operand" "")
8337           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8338      (set (match_operand:SI 6 "gpc_reg_operand" "")
8339           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8340   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8341   "*
8342 { return rs6000_output_load_multiple (operands); }"
8343   [(set_attr "type" "load")
8344    (set_attr "update" "yes")
8345    (set_attr "indexed" "yes")
8346    (set_attr "length" "32")])
8348 (define_insn "*ldmsi4"
8349   [(match_parallel 0 "load_multiple_operation"
8350     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8351           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8352      (set (match_operand:SI 3 "gpc_reg_operand" "")
8353           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8354      (set (match_operand:SI 4 "gpc_reg_operand" "")
8355           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8356      (set (match_operand:SI 5 "gpc_reg_operand" "")
8357           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8358   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8359   "*
8360 { return rs6000_output_load_multiple (operands); }"
8361   [(set_attr "type" "load")
8362    (set_attr "update" "yes")
8363    (set_attr "indexed" "yes")
8364    (set_attr "length" "32")])
8366 (define_insn "*ldmsi3"
8367   [(match_parallel 0 "load_multiple_operation"
8368     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8369           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8370      (set (match_operand:SI 3 "gpc_reg_operand" "")
8371           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8372      (set (match_operand:SI 4 "gpc_reg_operand" "")
8373           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8374   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8375   "*
8376 { return rs6000_output_load_multiple (operands); }"
8377   [(set_attr "type" "load")
8378    (set_attr "update" "yes")
8379    (set_attr "indexed" "yes")
8380    (set_attr "length" "32")])
8382 (define_expand "store_multiple"
8383   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8384                           (match_operand:SI 1 "" ""))
8385                      (clobber (scratch:SI))
8386                      (use (match_operand:SI 2 "" ""))])]
8387   "TARGET_STRING && !TARGET_POWERPC64"
8388   "
8390   int regno;
8391   int count;
8392   rtx to;
8393   rtx op0;
8394   int i;
8396   /* Support only storing a constant number of fixed-point registers to
8397      memory and only bother with this if more than two; the machine
8398      doesn't support more than eight.  */
8399   if (GET_CODE (operands[2]) != CONST_INT
8400       || INTVAL (operands[2]) <= 2
8401       || INTVAL (operands[2]) > 8
8402       || GET_CODE (operands[0]) != MEM
8403       || GET_CODE (operands[1]) != REG
8404       || REGNO (operands[1]) >= 32)
8405     FAIL;
8407   count = INTVAL (operands[2]);
8408   regno = REGNO (operands[1]);
8410   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8411   to = force_reg (SImode, XEXP (operands[0], 0));
8412   op0 = replace_equiv_address (operands[0], to);
8414   XVECEXP (operands[3], 0, 0)
8415     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8416   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8417                                                  gen_rtx_SCRATCH (SImode));
8419   for (i = 1; i < count; i++)
8420     XVECEXP (operands[3], 0, i + 1)
8421       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8422                      gen_rtx_REG (SImode, regno + i));
8425 (define_insn "*stmsi8"
8426   [(match_parallel 0 "store_multiple_operation"
8427     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8428           (match_operand:SI 2 "gpc_reg_operand" "r"))
8429      (clobber (match_scratch:SI 3 "=X"))
8430      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8431           (match_operand:SI 4 "gpc_reg_operand" "r"))
8432      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8433           (match_operand:SI 5 "gpc_reg_operand" "r"))
8434      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8435           (match_operand:SI 6 "gpc_reg_operand" "r"))
8436      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8437           (match_operand:SI 7 "gpc_reg_operand" "r"))
8438      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8439           (match_operand:SI 8 "gpc_reg_operand" "r"))
8440      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8441           (match_operand:SI 9 "gpc_reg_operand" "r"))
8442      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8443           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8444   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8445   "stswi %2,%1,%O0"
8446   [(set_attr "type" "store")
8447    (set_attr "update" "yes")
8448    (set_attr "indexed" "yes")
8449    (set_attr "cell_micro" "always")])
8451 (define_insn "*stmsi7"
8452   [(match_parallel 0 "store_multiple_operation"
8453     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8454           (match_operand:SI 2 "gpc_reg_operand" "r"))
8455      (clobber (match_scratch:SI 3 "=X"))
8456      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8457           (match_operand:SI 4 "gpc_reg_operand" "r"))
8458      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8459           (match_operand:SI 5 "gpc_reg_operand" "r"))
8460      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8461           (match_operand:SI 6 "gpc_reg_operand" "r"))
8462      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8463           (match_operand:SI 7 "gpc_reg_operand" "r"))
8464      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8465           (match_operand:SI 8 "gpc_reg_operand" "r"))
8466      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8467           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8468   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8469   "stswi %2,%1,%O0"
8470   [(set_attr "type" "store")
8471    (set_attr "update" "yes")
8472    (set_attr "indexed" "yes")
8473    (set_attr "cell_micro" "always")])
8475 (define_insn "*stmsi6"
8476   [(match_parallel 0 "store_multiple_operation"
8477     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8478           (match_operand:SI 2 "gpc_reg_operand" "r"))
8479      (clobber (match_scratch:SI 3 "=X"))
8480      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8481           (match_operand:SI 4 "gpc_reg_operand" "r"))
8482      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8483           (match_operand:SI 5 "gpc_reg_operand" "r"))
8484      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8485           (match_operand:SI 6 "gpc_reg_operand" "r"))
8486      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8487           (match_operand:SI 7 "gpc_reg_operand" "r"))
8488      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8489           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8490   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8491   "stswi %2,%1,%O0"
8492   [(set_attr "type" "store")
8493    (set_attr "update" "yes")
8494    (set_attr "indexed" "yes")
8495    (set_attr "cell_micro" "always")])
8497 (define_insn "*stmsi5"
8498   [(match_parallel 0 "store_multiple_operation"
8499     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8500           (match_operand:SI 2 "gpc_reg_operand" "r"))
8501      (clobber (match_scratch:SI 3 "=X"))
8502      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8503           (match_operand:SI 4 "gpc_reg_operand" "r"))
8504      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8505           (match_operand:SI 5 "gpc_reg_operand" "r"))
8506      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8507           (match_operand:SI 6 "gpc_reg_operand" "r"))
8508      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8509           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8510   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8511   "stswi %2,%1,%O0"
8512   [(set_attr "type" "store")
8513    (set_attr "update" "yes")
8514    (set_attr "indexed" "yes")
8515    (set_attr "cell_micro" "always")])
8517 (define_insn "*stmsi4"
8518   [(match_parallel 0 "store_multiple_operation"
8519     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8520           (match_operand:SI 2 "gpc_reg_operand" "r"))
8521      (clobber (match_scratch:SI 3 "=X"))
8522      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8523           (match_operand:SI 4 "gpc_reg_operand" "r"))
8524      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8525           (match_operand:SI 5 "gpc_reg_operand" "r"))
8526      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8527           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8528   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8529   "stswi %2,%1,%O0"
8530   [(set_attr "type" "store")
8531    (set_attr "update" "yes")
8532    (set_attr "indexed" "yes")
8533    (set_attr "cell_micro" "always")])
8535 (define_insn "*stmsi3"
8536   [(match_parallel 0 "store_multiple_operation"
8537     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8538           (match_operand:SI 2 "gpc_reg_operand" "r"))
8539      (clobber (match_scratch:SI 3 "=X"))
8540      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8541           (match_operand:SI 4 "gpc_reg_operand" "r"))
8542      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8543           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8544   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8545   "stswi %2,%1,%O0"
8546   [(set_attr "type" "store")
8547    (set_attr "update" "yes")
8548    (set_attr "indexed" "yes")
8549    (set_attr "cell_micro" "always")])
8551 (define_expand "setmemsi"
8552   [(parallel [(set (match_operand:BLK 0 "" "")
8553                    (match_operand 2 "const_int_operand" ""))
8554               (use (match_operand:SI 1 "" ""))
8555               (use (match_operand:SI 3 "" ""))])]
8556   ""
8557   "
8559   /* If value to set is not zero, use the library routine.  */
8560   if (operands[2] != const0_rtx)
8561     FAIL;
8563   if (expand_block_clear (operands))
8564     DONE;
8565   else
8566     FAIL;
8569 ;; String/block move insn.
8570 ;; Argument 0 is the destination
8571 ;; Argument 1 is the source
8572 ;; Argument 2 is the length
8573 ;; Argument 3 is the alignment
8575 (define_expand "movmemsi"
8576   [(parallel [(set (match_operand:BLK 0 "" "")
8577                    (match_operand:BLK 1 "" ""))
8578               (use (match_operand:SI 2 "" ""))
8579               (use (match_operand:SI 3 "" ""))])]
8580   ""
8581   "
8583   if (expand_block_move (operands))
8584     DONE;
8585   else
8586     FAIL;
8589 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8590 ;; register allocator doesn't have a clue about allocating 8 word registers.
8591 ;; rD/rS = r5 is preferred, efficient form.
8592 (define_expand "movmemsi_8reg"
8593   [(parallel [(set (match_operand 0 "" "")
8594                    (match_operand 1 "" ""))
8595               (use (match_operand 2 "" ""))
8596               (use (match_operand 3 "" ""))
8597               (clobber (reg:SI  5))
8598               (clobber (reg:SI  6))
8599               (clobber (reg:SI  7))
8600               (clobber (reg:SI  8))
8601               (clobber (reg:SI  9))
8602               (clobber (reg:SI 10))
8603               (clobber (reg:SI 11))
8604               (clobber (reg:SI 12))
8605               (clobber (match_scratch:SI 4 ""))])]
8606   "TARGET_STRING"
8607   "")
8609 (define_insn ""
8610   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8611         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8612    (use (match_operand:SI 2 "immediate_operand" "i"))
8613    (use (match_operand:SI 3 "immediate_operand" "i"))
8614    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8615    (clobber (reg:SI  6))
8616    (clobber (reg:SI  7))
8617    (clobber (reg:SI  8))
8618    (clobber (reg:SI  9))
8619    (clobber (reg:SI 10))
8620    (clobber (reg:SI 11))
8621    (clobber (reg:SI 12))
8622    (clobber (match_scratch:SI 5 "=X"))]
8623   "TARGET_STRING
8624    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8625        || INTVAL (operands[2]) == 0)
8626    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8627    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8628    && REGNO (operands[4]) == 5"
8629   "lswi %4,%1,%2\;stswi %4,%0,%2"
8630   [(set_attr "type" "store")
8631    (set_attr "update" "yes")
8632    (set_attr "indexed" "yes")
8633    (set_attr "cell_micro" "always")
8634    (set_attr "length" "8")])
8636 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8637 ;; register allocator doesn't have a clue about allocating 6 word registers.
8638 ;; rD/rS = r5 is preferred, efficient form.
8639 (define_expand "movmemsi_6reg"
8640   [(parallel [(set (match_operand 0 "" "")
8641                    (match_operand 1 "" ""))
8642               (use (match_operand 2 "" ""))
8643               (use (match_operand 3 "" ""))
8644               (clobber (reg:SI  5))
8645               (clobber (reg:SI  6))
8646               (clobber (reg:SI  7))
8647               (clobber (reg:SI  8))
8648               (clobber (reg:SI  9))
8649               (clobber (reg:SI 10))
8650               (clobber (match_scratch:SI 4 ""))])]
8651   "TARGET_STRING"
8652   "")
8654 (define_insn ""
8655   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8656         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8657    (use (match_operand:SI 2 "immediate_operand" "i"))
8658    (use (match_operand:SI 3 "immediate_operand" "i"))
8659    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8660    (clobber (reg:SI  6))
8661    (clobber (reg:SI  7))
8662    (clobber (reg:SI  8))
8663    (clobber (reg:SI  9))
8664    (clobber (reg:SI 10))
8665    (clobber (match_scratch:SI 5 "=X"))]
8666   "TARGET_STRING
8667    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8668    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8669    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8670    && REGNO (operands[4]) == 5"
8671   "lswi %4,%1,%2\;stswi %4,%0,%2"
8672   [(set_attr "type" "store")
8673    (set_attr "update" "yes")
8674    (set_attr "indexed" "yes")
8675    (set_attr "cell_micro" "always")
8676    (set_attr "length" "8")])
8678 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8679 ;; problems with TImode.
8680 ;; rD/rS = r5 is preferred, efficient form.
8681 (define_expand "movmemsi_4reg"
8682   [(parallel [(set (match_operand 0 "" "")
8683                    (match_operand 1 "" ""))
8684               (use (match_operand 2 "" ""))
8685               (use (match_operand 3 "" ""))
8686               (clobber (reg:SI 5))
8687               (clobber (reg:SI 6))
8688               (clobber (reg:SI 7))
8689               (clobber (reg:SI 8))
8690               (clobber (match_scratch:SI 4 ""))])]
8691   "TARGET_STRING"
8692   "")
8694 (define_insn ""
8695   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8696         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8697    (use (match_operand:SI 2 "immediate_operand" "i"))
8698    (use (match_operand:SI 3 "immediate_operand" "i"))
8699    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8700    (clobber (reg:SI 6))
8701    (clobber (reg:SI 7))
8702    (clobber (reg:SI 8))
8703    (clobber (match_scratch:SI 5 "=X"))]
8704   "TARGET_STRING
8705    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8706    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8707    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8708    && REGNO (operands[4]) == 5"
8709   "lswi %4,%1,%2\;stswi %4,%0,%2"
8710   [(set_attr "type" "store")
8711    (set_attr "update" "yes")
8712    (set_attr "indexed" "yes")
8713    (set_attr "cell_micro" "always")
8714    (set_attr "length" "8")])
8716 ;; Move up to 8 bytes at a time.
8717 (define_expand "movmemsi_2reg"
8718   [(parallel [(set (match_operand 0 "" "")
8719                    (match_operand 1 "" ""))
8720               (use (match_operand 2 "" ""))
8721               (use (match_operand 3 "" ""))
8722               (clobber (match_scratch:DI 4 ""))
8723               (clobber (match_scratch:SI 5 ""))])]
8724   "TARGET_STRING && ! TARGET_POWERPC64"
8725   "")
8727 (define_insn ""
8728   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8729         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8730    (use (match_operand:SI 2 "immediate_operand" "i"))
8731    (use (match_operand:SI 3 "immediate_operand" "i"))
8732    (clobber (match_scratch:DI 4 "=&r"))
8733    (clobber (match_scratch:SI 5 "=X"))]
8734   "TARGET_STRING && ! TARGET_POWERPC64
8735    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8736   "lswi %4,%1,%2\;stswi %4,%0,%2"
8737   [(set_attr "type" "store")
8738    (set_attr "update" "yes")
8739    (set_attr "indexed" "yes")
8740    (set_attr "cell_micro" "always")
8741    (set_attr "length" "8")])
8743 ;; Move up to 4 bytes at a time.
8744 (define_expand "movmemsi_1reg"
8745   [(parallel [(set (match_operand 0 "" "")
8746                    (match_operand 1 "" ""))
8747               (use (match_operand 2 "" ""))
8748               (use (match_operand 3 "" ""))
8749               (clobber (match_scratch:SI 4 ""))
8750               (clobber (match_scratch:SI 5 ""))])]
8751   "TARGET_STRING"
8752   "")
8754 (define_insn ""
8755   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8756         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8757    (use (match_operand:SI 2 "immediate_operand" "i"))
8758    (use (match_operand:SI 3 "immediate_operand" "i"))
8759    (clobber (match_scratch:SI 4 "=&r"))
8760    (clobber (match_scratch:SI 5 "=X"))]
8761   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8762   "lswi %4,%1,%2\;stswi %4,%0,%2"
8763   [(set_attr "type" "store")
8764    (set_attr "update" "yes")
8765    (set_attr "indexed" "yes")
8766    (set_attr "cell_micro" "always")
8767    (set_attr "length" "8")])
8769 ;; Define insns that do load or store with update.  Some of these we can
8770 ;; get by using pre-decrement or pre-increment, but the hardware can also
8771 ;; do cases where the increment is not the size of the object.
8773 ;; In all these cases, we use operands 0 and 1 for the register being
8774 ;; incremented because those are the operands that local-alloc will
8775 ;; tie and these are the pair most likely to be tieable (and the ones
8776 ;; that will benefit the most).
8778 (define_insn "*movdi_update1"
8779   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8780         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8781                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8782    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8783         (plus:DI (match_dup 1) (match_dup 2)))]
8784   "TARGET_POWERPC64 && TARGET_UPDATE
8785    && (!avoiding_indexed_address_p (DImode)
8786        || !gpc_reg_operand (operands[2], DImode))"
8787   "@
8788    ldux %3,%0,%2
8789    ldu %3,%2(%0)"
8790   [(set_attr "type" "load")
8791    (set_attr "update" "yes")
8792    (set_attr "indexed" "yes,no")])
8794 (define_insn "movdi_<mode>_update"
8795   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8796                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8797         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8798    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8799         (plus:P (match_dup 1) (match_dup 2)))]
8800   "TARGET_POWERPC64 && TARGET_UPDATE
8801    && (!avoiding_indexed_address_p (Pmode)
8802        || !gpc_reg_operand (operands[2], Pmode)
8803        || (REG_P (operands[0])
8804            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8805   "@
8806    stdux %3,%0,%2
8807    stdu %3,%2(%0)"
8808   [(set_attr "type" "store")
8809    (set_attr "update" "yes")
8810    (set_attr "indexed" "yes,no")])
8812 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8813 ;; needed for stack allocation, even if the user passes -mno-update.
8814 (define_insn "movdi_<mode>_update_stack"
8815   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8816                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8817         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8818    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8819         (plus:P (match_dup 1) (match_dup 2)))]
8820   "TARGET_POWERPC64"
8821   "@
8822    stdux %3,%0,%2
8823    stdu %3,%2(%0)"
8824   [(set_attr "type" "store")
8825    (set_attr "update" "yes")
8826    (set_attr "indexed" "yes,no")])
8828 (define_insn "*movsi_update1"
8829   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8830         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8831                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8832    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8833         (plus:SI (match_dup 1) (match_dup 2)))]
8834   "TARGET_UPDATE
8835    && (!avoiding_indexed_address_p (SImode)
8836        || !gpc_reg_operand (operands[2], SImode))"
8837   "@
8838    lwzux %3,%0,%2
8839    lwzu %3,%2(%0)"
8840   [(set_attr "type" "load")
8841    (set_attr "update" "yes")
8842    (set_attr "indexed" "yes,no")])
8844 (define_insn "*movsi_update2"
8845   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8846         (sign_extend:DI
8847          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8848                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8849    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8850         (plus:DI (match_dup 1) (match_dup 2)))]
8851   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8852    && !avoiding_indexed_address_p (DImode)"
8853   "lwaux %3,%0,%2"
8854   [(set_attr "type" "load")
8855    (set_attr "sign_extend" "yes")
8856    (set_attr "update" "yes")
8857    (set_attr "indexed" "yes")])
8859 (define_insn "movsi_update"
8860   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8861                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8862         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8863    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8864         (plus:SI (match_dup 1) (match_dup 2)))]
8865   "TARGET_UPDATE
8866    && (!avoiding_indexed_address_p (SImode)
8867        || !gpc_reg_operand (operands[2], SImode)
8868        || (REG_P (operands[0])
8869            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8870   "@
8871    stwux %3,%0,%2
8872    stwu %3,%2(%0)"
8873   [(set_attr "type" "store")
8874    (set_attr "update" "yes")
8875    (set_attr "indexed" "yes,no")])
8877 ;; This is an unconditional pattern; needed for stack allocation, even
8878 ;; if the user passes -mno-update.
8879 (define_insn "movsi_update_stack"
8880   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8881                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8882         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8883    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8884         (plus:SI (match_dup 1) (match_dup 2)))]
8885   ""
8886   "@
8887    stwux %3,%0,%2
8888    stwu %3,%2(%0)"
8889   [(set_attr "type" "store")
8890    (set_attr "update" "yes")
8891    (set_attr "indexed" "yes,no")])
8893 (define_insn "*movhi_update1"
8894   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8895         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8896                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8897    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8898         (plus:SI (match_dup 1) (match_dup 2)))]
8899   "TARGET_UPDATE
8900    && (!avoiding_indexed_address_p (SImode)
8901        || !gpc_reg_operand (operands[2], SImode))"
8902   "@
8903    lhzux %3,%0,%2
8904    lhzu %3,%2(%0)"
8905   [(set_attr "type" "load")
8906    (set_attr "update" "yes")
8907    (set_attr "indexed" "yes,no")])
8909 (define_insn "*movhi_update2"
8910   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8911         (zero_extend:SI
8912          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8913                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8914    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8915         (plus:SI (match_dup 1) (match_dup 2)))]
8916   "TARGET_UPDATE
8917    && (!avoiding_indexed_address_p (SImode)
8918        || !gpc_reg_operand (operands[2], SImode))"
8919   "@
8920    lhzux %3,%0,%2
8921    lhzu %3,%2(%0)"
8922   [(set_attr "type" "load")
8923    (set_attr "update" "yes")
8924    (set_attr "indexed" "yes,no")])
8926 (define_insn "*movhi_update3"
8927   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8928         (sign_extend:SI
8929          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8930                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8931    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8932         (plus:SI (match_dup 1) (match_dup 2)))]
8933   "TARGET_UPDATE && rs6000_gen_cell_microcode
8934    && (!avoiding_indexed_address_p (SImode)
8935        || !gpc_reg_operand (operands[2], SImode))"
8936   "@
8937    lhaux %3,%0,%2
8938    lhau %3,%2(%0)"
8939   [(set_attr "type" "load")
8940    (set_attr "sign_extend" "yes")
8941    (set_attr "update" "yes")
8942    (set_attr "indexed" "yes,no")])
8944 (define_insn "*movhi_update4"
8945   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8946                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8947         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8948    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8949         (plus:SI (match_dup 1) (match_dup 2)))]
8950   "TARGET_UPDATE
8951    && (!avoiding_indexed_address_p (SImode)
8952        || !gpc_reg_operand (operands[2], SImode))"
8953   "@
8954    sthux %3,%0,%2
8955    sthu %3,%2(%0)"
8956   [(set_attr "type" "store")
8957    (set_attr "update" "yes")
8958    (set_attr "indexed" "yes,no")])
8960 (define_insn "*movqi_update1"
8961   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8962         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8963                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8964    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8965         (plus:SI (match_dup 1) (match_dup 2)))]
8966   "TARGET_UPDATE
8967    && (!avoiding_indexed_address_p (SImode)
8968        || !gpc_reg_operand (operands[2], SImode))"
8969   "@
8970    lbzux %3,%0,%2
8971    lbzu %3,%2(%0)"
8972   [(set_attr "type" "load")
8973    (set_attr "update" "yes")
8974    (set_attr "indexed" "yes,no")])
8976 (define_insn "*movqi_update2"
8977   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8978         (zero_extend:SI
8979          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8980                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8981    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8982         (plus:SI (match_dup 1) (match_dup 2)))]
8983   "TARGET_UPDATE
8984    && (!avoiding_indexed_address_p (SImode)
8985        || !gpc_reg_operand (operands[2], SImode))"
8986   "@
8987    lbzux %3,%0,%2
8988    lbzu %3,%2(%0)"
8989   [(set_attr "type" "load")
8990    (set_attr "update" "yes")
8991    (set_attr "indexed" "yes,no")])
8993 (define_insn "*movqi_update3"
8994   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8995                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8996         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8997    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8998         (plus:SI (match_dup 1) (match_dup 2)))]
8999   "TARGET_UPDATE
9000    && (!avoiding_indexed_address_p (SImode)
9001        || !gpc_reg_operand (operands[2], SImode))"
9002   "@
9003    stbux %3,%0,%2
9004    stbu %3,%2(%0)"
9005   [(set_attr "type" "store")
9006    (set_attr "update" "yes")
9007    (set_attr "indexed" "yes,no")])
9009 (define_insn "*movsf_update1"
9010   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9011         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9012                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9013    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9014         (plus:SI (match_dup 1) (match_dup 2)))]
9015   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9016    && (!avoiding_indexed_address_p (SImode)
9017        || !gpc_reg_operand (operands[2], SImode))"
9018   "@
9019    lfsux %3,%0,%2
9020    lfsu %3,%2(%0)"
9021   [(set_attr "type" "fpload")
9022    (set_attr "update" "yes")
9023    (set_attr "indexed" "yes,no")])
9025 (define_insn "*movsf_update2"
9026   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9027                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9028         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9029    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9030         (plus:SI (match_dup 1) (match_dup 2)))]
9031   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9032    && (!avoiding_indexed_address_p (SImode)
9033        || !gpc_reg_operand (operands[2], SImode))"
9034   "@
9035    stfsux %3,%0,%2
9036    stfsu %3,%2(%0)"
9037   [(set_attr "type" "fpstore")
9038    (set_attr "update" "yes")
9039    (set_attr "indexed" "yes,no")])
9041 (define_insn "*movsf_update3"
9042   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9043         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9044                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9045    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9046         (plus:SI (match_dup 1) (match_dup 2)))]
9047   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9048    && (!avoiding_indexed_address_p (SImode)
9049        || !gpc_reg_operand (operands[2], SImode))"
9050   "@
9051    lwzux %3,%0,%2
9052    lwzu %3,%2(%0)"
9053   [(set_attr "type" "load")
9054    (set_attr "update" "yes")
9055    (set_attr "indexed" "yes,no")])
9057 (define_insn "*movsf_update4"
9058   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9059                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9060         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9061    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9062         (plus:SI (match_dup 1) (match_dup 2)))]
9063   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9064    && (!avoiding_indexed_address_p (SImode)
9065        || !gpc_reg_operand (operands[2], SImode))"
9066   "@
9067    stwux %3,%0,%2
9068    stwu %3,%2(%0)"
9069   [(set_attr "type" "store")
9070    (set_attr "update" "yes")
9071    (set_attr "indexed" "yes,no")])
9073 (define_insn "*movdf_update1"
9074   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9075         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9076                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9077    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9078         (plus:SI (match_dup 1) (match_dup 2)))]
9079   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9080    && (!avoiding_indexed_address_p (SImode)
9081        || !gpc_reg_operand (operands[2], SImode))"
9082   "@
9083    lfdux %3,%0,%2
9084    lfdu %3,%2(%0)"
9085   [(set_attr "type" "fpload")
9086    (set_attr "update" "yes")
9087    (set_attr "indexed" "yes,no")
9088    (set_attr "size" "64")])
9090 (define_insn "*movdf_update2"
9091   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9092                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9093         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9094    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9095         (plus:SI (match_dup 1) (match_dup 2)))]
9096   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9097    && (!avoiding_indexed_address_p (SImode)
9098        || !gpc_reg_operand (operands[2], SImode))"
9099   "@
9100    stfdux %3,%0,%2
9101    stfdu %3,%2(%0)"
9102   [(set_attr "type" "fpstore")
9103    (set_attr "update" "yes")
9104    (set_attr "indexed" "yes,no")])
9107 ;; After inserting conditional returns we can sometimes have
9108 ;; unnecessary register moves.  Unfortunately we cannot have a
9109 ;; modeless peephole here, because some single SImode sets have early
9110 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9111 ;; sequences, using get_attr_length here will smash the operands
9112 ;; array.  Neither is there an early_cobbler_p predicate.
9113 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9114 ;; Also this optimization interferes with scalars going into
9115 ;; altivec registers (the code does reloading through the FPRs).
9116 (define_peephole2
9117   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9118         (match_operand:DF 1 "any_operand" ""))
9119    (set (match_operand:DF 2 "gpc_reg_operand" "")
9120         (match_dup 0))]
9121   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9122    && !TARGET_UPPER_REGS_DF
9123    && peep2_reg_dead_p (2, operands[0])"
9124   [(set (match_dup 2) (match_dup 1))])
9126 (define_peephole2
9127   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9128         (match_operand:SF 1 "any_operand" ""))
9129    (set (match_operand:SF 2 "gpc_reg_operand" "")
9130         (match_dup 0))]
9131   "!TARGET_UPPER_REGS_SF
9132    && peep2_reg_dead_p (2, operands[0])"
9133   [(set (match_dup 2) (match_dup 1))])
9136 ;; TLS support.
9138 ;; Mode attributes for different ABIs.
9139 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9140 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9141 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9142 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9144 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9145   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9146         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9147               (match_operand 4 "" "g")))
9148    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9149                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9150                    UNSPEC_TLSGD)
9151    (clobber (reg:SI LR_REGNO))]
9152   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9154   if (TARGET_CMODEL != CMODEL_SMALL)
9155     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9156            "bl %z3\;nop";
9157   else
9158     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9160   "&& TARGET_TLS_MARKERS"
9161   [(set (match_dup 0)
9162         (unspec:TLSmode [(match_dup 1)
9163                          (match_dup 2)]
9164                         UNSPEC_TLSGD))
9165    (parallel [(set (match_dup 0)
9166                    (call (mem:TLSmode (match_dup 3))
9167                          (match_dup 4)))
9168               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9169               (clobber (reg:SI LR_REGNO))])]
9170   ""
9171   [(set_attr "type" "two")
9172    (set (attr "length")
9173      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9174                    (const_int 16)
9175                    (const_int 12)))])
9177 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9178   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9179         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9180               (match_operand 4 "" "g")))
9181    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9182                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9183                    UNSPEC_TLSGD)
9184    (clobber (reg:SI LR_REGNO))]
9185   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9187   if (flag_pic)
9188     {
9189       if (TARGET_SECURE_PLT && flag_pic == 2)
9190         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9191       else
9192         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9193     }
9194   else
9195     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9197   "&& TARGET_TLS_MARKERS"
9198   [(set (match_dup 0)
9199         (unspec:TLSmode [(match_dup 1)
9200                          (match_dup 2)]
9201                         UNSPEC_TLSGD))
9202    (parallel [(set (match_dup 0)
9203                    (call (mem:TLSmode (match_dup 3))
9204                          (match_dup 4)))
9205               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9206               (clobber (reg:SI LR_REGNO))])]
9207   ""
9208   [(set_attr "type" "two")
9209    (set_attr "length" "8")])
9211 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9212   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9213         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9214                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9215                         UNSPEC_TLSGD))]
9216   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9217   "addi %0,%1,%2@got@tlsgd"
9218   "&& TARGET_CMODEL != CMODEL_SMALL"
9219   [(set (match_dup 3)
9220         (high:TLSmode
9221             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9222    (set (match_dup 0)
9223         (lo_sum:TLSmode (match_dup 3)
9224             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9225   "
9227   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9229   [(set (attr "length")
9230      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9231                    (const_int 8)
9232                    (const_int 4)))])
9234 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9235   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9236      (high:TLSmode
9237        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9238                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9239                        UNSPEC_TLSGD)))]
9240   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9241   "addis %0,%1,%2@got@tlsgd@ha"
9242   [(set_attr "length" "4")])
9244 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9245   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9246      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9247        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9248                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9249                        UNSPEC_TLSGD)))]
9250   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9251   "addi %0,%1,%2@got@tlsgd@l"
9252   [(set_attr "length" "4")])
9254 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9255   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9256         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9257               (match_operand 2 "" "g")))
9258    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9259                    UNSPEC_TLSGD)
9260    (clobber (reg:SI LR_REGNO))]
9261   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9262    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9263   "bl %z1(%3@tlsgd)\;nop"
9264   [(set_attr "type" "branch")
9265    (set_attr "length" "8")])
9267 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9268   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9269         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9270               (match_operand 2 "" "g")))
9271    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9272                    UNSPEC_TLSGD)
9273    (clobber (reg:SI LR_REGNO))]
9274   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9276   if (flag_pic)
9277     {
9278       if (TARGET_SECURE_PLT && flag_pic == 2)
9279         return "bl %z1+32768(%3@tlsgd)@plt";
9280       return "bl %z1(%3@tlsgd)@plt";
9281     }
9282   return "bl %z1(%3@tlsgd)";
9284   [(set_attr "type" "branch")
9285    (set_attr "length" "4")])
9287 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9288   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9289         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9290               (match_operand 3 "" "g")))
9291    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9292                    UNSPEC_TLSLD)
9293    (clobber (reg:SI LR_REGNO))]
9294   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9296   if (TARGET_CMODEL != CMODEL_SMALL)
9297     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9298            "bl %z2\;nop";
9299   else
9300     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9302   "&& TARGET_TLS_MARKERS"
9303   [(set (match_dup 0)
9304         (unspec:TLSmode [(match_dup 1)]
9305                         UNSPEC_TLSLD))
9306    (parallel [(set (match_dup 0)
9307                    (call (mem:TLSmode (match_dup 2))
9308                          (match_dup 3)))
9309               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9310               (clobber (reg:SI LR_REGNO))])]
9311   ""
9312   [(set_attr "type" "two")
9313    (set (attr "length")
9314      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9315                    (const_int 16)
9316                    (const_int 12)))])
9318 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9319   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9320         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9321               (match_operand 3 "" "g")))
9322    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9323                    UNSPEC_TLSLD)
9324    (clobber (reg:SI LR_REGNO))]
9325   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9327   if (flag_pic)
9328     {
9329       if (TARGET_SECURE_PLT && flag_pic == 2)
9330         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9331       else
9332         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9333     }
9334   else
9335     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9337   "&& TARGET_TLS_MARKERS"
9338   [(set (match_dup 0)
9339         (unspec:TLSmode [(match_dup 1)]
9340                         UNSPEC_TLSLD))
9341    (parallel [(set (match_dup 0)
9342                    (call (mem:TLSmode (match_dup 2))
9343                          (match_dup 3)))
9344               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9345               (clobber (reg:SI LR_REGNO))])]
9346   ""
9347   [(set_attr "length" "8")])
9349 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9350   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9351         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9352                         UNSPEC_TLSLD))]
9353   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9354   "addi %0,%1,%&@got@tlsld"
9355   "&& TARGET_CMODEL != CMODEL_SMALL"
9356   [(set (match_dup 2)
9357         (high:TLSmode
9358             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9359    (set (match_dup 0)
9360         (lo_sum:TLSmode (match_dup 2)
9361             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9362   "
9364   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9366   [(set (attr "length")
9367      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9368                    (const_int 8)
9369                    (const_int 4)))])
9371 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9372   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9373      (high:TLSmode
9374        (unspec:TLSmode [(const_int 0)
9375                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9376                        UNSPEC_TLSLD)))]
9377   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9378   "addis %0,%1,%&@got@tlsld@ha"
9379   [(set_attr "length" "4")])
9381 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9382   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9383      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9384        (unspec:TLSmode [(const_int 0)
9385                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9386                        UNSPEC_TLSLD)))]
9387   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9388   "addi %0,%1,%&@got@tlsld@l"
9389   [(set_attr "length" "4")])
9391 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9392   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9393         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9394               (match_operand 2 "" "g")))
9395    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9396    (clobber (reg:SI LR_REGNO))]
9397   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9398    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9399   "bl %z1(%&@tlsld)\;nop"
9400   [(set_attr "type" "branch")
9401    (set_attr "length" "8")])
9403 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9404   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9405         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9406               (match_operand 2 "" "g")))
9407    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9408    (clobber (reg:SI LR_REGNO))]
9409   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9411   if (flag_pic)
9412     {
9413       if (TARGET_SECURE_PLT && flag_pic == 2)
9414         return "bl %z1+32768(%&@tlsld)@plt";
9415       return "bl %z1(%&@tlsld)@plt";
9416     }
9417   return "bl %z1(%&@tlsld)";
9419   [(set_attr "type" "branch")
9420    (set_attr "length" "4")])
9422 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9423   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9424         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9425                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9426                         UNSPEC_TLSDTPREL))]
9427   "HAVE_AS_TLS"
9428   "addi %0,%1,%2@dtprel")
9430 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9431   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9432         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9433                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9434                         UNSPEC_TLSDTPRELHA))]
9435   "HAVE_AS_TLS"
9436   "addis %0,%1,%2@dtprel@ha")
9438 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9439   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9440         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9441                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9442                         UNSPEC_TLSDTPRELLO))]
9443   "HAVE_AS_TLS"
9444   "addi %0,%1,%2@dtprel@l")
9446 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9447   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9448         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9449                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9450                         UNSPEC_TLSGOTDTPREL))]
9451   "HAVE_AS_TLS"
9452   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9453   "&& TARGET_CMODEL != CMODEL_SMALL"
9454   [(set (match_dup 3)
9455         (high:TLSmode
9456             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9457    (set (match_dup 0)
9458         (lo_sum:TLSmode (match_dup 3)
9459             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9460   "
9462   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9464   [(set (attr "length")
9465      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9466                    (const_int 8)
9467                    (const_int 4)))])
9469 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9470   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9471      (high:TLSmode
9472        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9473                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9474                        UNSPEC_TLSGOTDTPREL)))]
9475   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9476   "addis %0,%1,%2@got@dtprel@ha"
9477   [(set_attr "length" "4")])
9479 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9480   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9481      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9482          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9483                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9484                          UNSPEC_TLSGOTDTPREL)))]
9485   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9486   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9487   [(set_attr "length" "4")])
9489 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9490   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9491         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9492                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9493                         UNSPEC_TLSTPREL))]
9494   "HAVE_AS_TLS"
9495   "addi %0,%1,%2@tprel")
9497 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9498   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9499         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9500                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9501                         UNSPEC_TLSTPRELHA))]
9502   "HAVE_AS_TLS"
9503   "addis %0,%1,%2@tprel@ha")
9505 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9506   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9507         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9508                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9509                         UNSPEC_TLSTPRELLO))]
9510   "HAVE_AS_TLS"
9511   "addi %0,%1,%2@tprel@l")
9513 ;; "b" output constraint here and on tls_tls input to support linker tls
9514 ;; optimization.  The linker may edit the instructions emitted by a
9515 ;; tls_got_tprel/tls_tls pair to addis,addi.
9516 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9517   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9518         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9519                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9520                         UNSPEC_TLSGOTTPREL))]
9521   "HAVE_AS_TLS"
9522   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9523   "&& TARGET_CMODEL != CMODEL_SMALL"
9524   [(set (match_dup 3)
9525         (high:TLSmode
9526             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9527    (set (match_dup 0)
9528         (lo_sum:TLSmode (match_dup 3)
9529             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9530   "
9532   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9534   [(set (attr "length")
9535      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9536                    (const_int 8)
9537                    (const_int 4)))])
9539 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9540   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9541      (high:TLSmode
9542        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9543                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9544                        UNSPEC_TLSGOTTPREL)))]
9545   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9546   "addis %0,%1,%2@got@tprel@ha"
9547   [(set_attr "length" "4")])
9549 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9550   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9551      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9552          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9553                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9554                          UNSPEC_TLSGOTTPREL)))]
9555   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9556   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9557   [(set_attr "length" "4")])
9559 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9560   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9561         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9562                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9563                         UNSPEC_TLSTLS))]
9564   "TARGET_ELF && HAVE_AS_TLS"
9565   "add %0,%1,%2@tls")
9567 (define_expand "tls_get_tpointer"
9568   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9569         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9570   "TARGET_XCOFF && HAVE_AS_TLS"
9571   "
9573   emit_insn (gen_tls_get_tpointer_internal ());
9574   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9575   DONE;
9578 (define_insn "tls_get_tpointer_internal"
9579   [(set (reg:SI 3)
9580         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9581    (clobber (reg:SI LR_REGNO))]
9582   "TARGET_XCOFF && HAVE_AS_TLS"
9583   "bla __get_tpointer")
9585 (define_expand "tls_get_addr<mode>"
9586   [(set (match_operand:P 0 "gpc_reg_operand" "")
9587         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9588                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9589   "TARGET_XCOFF && HAVE_AS_TLS"
9590   "
9592   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9593   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9594   emit_insn (gen_tls_get_addr_internal<mode> ());
9595   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9596   DONE;
9599 (define_insn "tls_get_addr_internal<mode>"
9600   [(set (reg:P 3)
9601         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9602    (clobber (reg:P 0))
9603    (clobber (reg:P 4))
9604    (clobber (reg:P 5))
9605    (clobber (reg:P 11))
9606    (clobber (reg:CC CR0_REGNO))
9607    (clobber (reg:P LR_REGNO))]
9608   "TARGET_XCOFF && HAVE_AS_TLS"
9609   "bla __tls_get_addr")
9611 ;; Next come insns related to the calling sequence.
9613 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9614 ;; We move the back-chain and decrement the stack pointer.
9616 (define_expand "allocate_stack"
9617   [(set (match_operand 0 "gpc_reg_operand" "")
9618         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9619    (set (reg 1)
9620         (minus (reg 1) (match_dup 1)))]
9621   ""
9622   "
9623 { rtx chain = gen_reg_rtx (Pmode);
9624   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9625   rtx neg_op0;
9626   rtx insn, par, set, mem;
9628   emit_move_insn (chain, stack_bot);
9630   /* Check stack bounds if necessary.  */
9631   if (crtl->limit_stack)
9632     {
9633       rtx available;
9634       available = expand_binop (Pmode, sub_optab,
9635                                 stack_pointer_rtx, stack_limit_rtx,
9636                                 NULL_RTX, 1, OPTAB_WIDEN);
9637       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9638     }
9640   if (GET_CODE (operands[1]) != CONST_INT
9641       || INTVAL (operands[1]) < -32767
9642       || INTVAL (operands[1]) > 32768)
9643     {
9644       neg_op0 = gen_reg_rtx (Pmode);
9645       if (TARGET_32BIT)
9646         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9647       else
9648         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9649     }
9650   else
9651     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9653   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9654                                        : gen_movdi_di_update_stack))
9655                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9656                          chain));
9657   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9658      it now and set the alias set/attributes. The above gen_*_update
9659      calls will generate a PARALLEL with the MEM set being the first
9660      operation. */
9661   par = PATTERN (insn);
9662   gcc_assert (GET_CODE (par) == PARALLEL);
9663   set = XVECEXP (par, 0, 0);
9664   gcc_assert (GET_CODE (set) == SET);
9665   mem = SET_DEST (set);
9666   gcc_assert (MEM_P (mem));
9667   MEM_NOTRAP_P (mem) = 1;
9668   set_mem_alias_set (mem, get_frame_alias_set ());
9670   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9671   DONE;
9674 ;; These patterns say how to save and restore the stack pointer.  We need not
9675 ;; save the stack pointer at function level since we are careful to
9676 ;; preserve the backchain.  At block level, we have to restore the backchain
9677 ;; when we restore the stack pointer.
9679 ;; For nonlocal gotos, we must save both the stack pointer and its
9680 ;; backchain and restore both.  Note that in the nonlocal case, the
9681 ;; save area is a memory location.
9683 (define_expand "save_stack_function"
9684   [(match_operand 0 "any_operand" "")
9685    (match_operand 1 "any_operand" "")]
9686   ""
9687   "DONE;")
9689 (define_expand "restore_stack_function"
9690   [(match_operand 0 "any_operand" "")
9691    (match_operand 1 "any_operand" "")]
9692   ""
9693   "DONE;")
9695 ;; Adjust stack pointer (op0) to a new value (op1).
9696 ;; First copy old stack backchain to new location, and ensure that the
9697 ;; scheduler won't reorder the sp assignment before the backchain write.
9698 (define_expand "restore_stack_block"
9699   [(set (match_dup 2) (match_dup 3))
9700    (set (match_dup 4) (match_dup 2))
9701    (match_dup 5)
9702    (set (match_operand 0 "register_operand" "")
9703         (match_operand 1 "register_operand" ""))]
9704   ""
9705   "
9707   rtvec p;
9709   operands[1] = force_reg (Pmode, operands[1]);
9710   operands[2] = gen_reg_rtx (Pmode);
9711   operands[3] = gen_frame_mem (Pmode, operands[0]);
9712   operands[4] = gen_frame_mem (Pmode, operands[1]);
9713   p = rtvec_alloc (1);
9714   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9715                                   const0_rtx);
9716   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9719 (define_expand "save_stack_nonlocal"
9720   [(set (match_dup 3) (match_dup 4))
9721    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9722    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9723   ""
9724   "
9726   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9728   /* Copy the backchain to the first word, sp to the second.  */
9729   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9730   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9731   operands[3] = gen_reg_rtx (Pmode);
9732   operands[4] = gen_frame_mem (Pmode, operands[1]);
9735 (define_expand "restore_stack_nonlocal"
9736   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9737    (set (match_dup 3) (match_dup 4))
9738    (set (match_dup 5) (match_dup 2))
9739    (match_dup 6)
9740    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9741   ""
9742   "
9744   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9745   rtvec p;
9747   /* Restore the backchain from the first word, sp from the second.  */
9748   operands[2] = gen_reg_rtx (Pmode);
9749   operands[3] = gen_reg_rtx (Pmode);
9750   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9751   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9752   operands[5] = gen_frame_mem (Pmode, operands[3]);
9753   p = rtvec_alloc (1);
9754   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9755                                   const0_rtx);
9756   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9759 ;; TOC register handling.
9761 ;; Code to initialize the TOC register...
9763 (define_insn "load_toc_aix_si"
9764   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9765                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9766               (use (reg:SI 2))])]
9767   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9768   "*
9770   char buf[30];
9771   extern int need_toc_init;
9772   need_toc_init = 1;
9773   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9774   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9775   operands[2] = gen_rtx_REG (Pmode, 2);
9776   return \"lwz %0,%1(%2)\";
9778   [(set_attr "type" "load")
9779    (set_attr "update" "no")
9780    (set_attr "indexed" "no")])
9782 (define_insn "load_toc_aix_di"
9783   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9784                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9785               (use (reg:DI 2))])]
9786   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9787   "*
9789   char buf[30];
9790   extern int need_toc_init;
9791   need_toc_init = 1;
9792   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9793                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9794   if (TARGET_ELF)
9795     strcat (buf, \"@toc\");
9796   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9797   operands[2] = gen_rtx_REG (Pmode, 2);
9798   return \"ld %0,%1(%2)\";
9800   [(set_attr "type" "load")
9801    (set_attr "update" "no")
9802    (set_attr "indexed" "no")])
9804 (define_insn "load_toc_v4_pic_si"
9805   [(set (reg:SI LR_REGNO)
9806         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9807   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9808   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9809   [(set_attr "type" "branch")
9810    (set_attr "length" "4")])
9812 (define_expand "load_toc_v4_PIC_1"
9813   [(parallel [(set (reg:SI LR_REGNO)
9814                    (match_operand:SI 0 "immediate_operand" "s"))
9815               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9816   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9817    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9818   "")
9820 (define_insn "load_toc_v4_PIC_1_normal"
9821   [(set (reg:SI LR_REGNO)
9822         (match_operand:SI 0 "immediate_operand" "s"))
9823    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9824   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9825    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9826   "bcl 20,31,%0\\n%0:"
9827   [(set_attr "type" "branch")
9828    (set_attr "length" "4")
9829    (set_attr "cannot_copy" "yes")])
9831 (define_insn "load_toc_v4_PIC_1_476"
9832   [(set (reg:SI LR_REGNO)
9833         (match_operand:SI 0 "immediate_operand" "s"))
9834    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9835   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9836    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9837   "*
9839   char name[32];
9840   static char templ[32];
9842   get_ppc476_thunk_name (name);
9843   sprintf (templ, \"bl %s\\n%%0:\", name);
9844   return templ;
9846   [(set_attr "type" "branch")
9847    (set_attr "length" "4")
9848    (set_attr "cannot_copy" "yes")])
9850 (define_expand "load_toc_v4_PIC_1b"
9851   [(parallel [(set (reg:SI LR_REGNO)
9852                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9853                                (label_ref (match_operand 1 "" ""))]
9854                            UNSPEC_TOCPTR))
9855               (match_dup 1)])]
9856   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9857   "")
9859 (define_insn "load_toc_v4_PIC_1b_normal"
9860   [(set (reg:SI LR_REGNO)
9861         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9862                     (label_ref (match_operand 1 "" ""))]
9863                 UNSPEC_TOCPTR))
9864    (match_dup 1)]
9865   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9866   "bcl 20,31,$+8\;.long %0-$"
9867   [(set_attr "type" "branch")
9868    (set_attr "length" "8")])
9870 (define_insn "load_toc_v4_PIC_1b_476"
9871   [(set (reg:SI LR_REGNO)
9872         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9873                     (label_ref (match_operand 1 "" ""))]
9874                 UNSPEC_TOCPTR))
9875    (match_dup 1)]
9876   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9877   "*
9879   char name[32];
9880   static char templ[32];
9882   get_ppc476_thunk_name (name);
9883   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9884   return templ;
9886   [(set_attr "type" "branch")
9887    (set_attr "length" "16")])
9889 (define_insn "load_toc_v4_PIC_2"
9890   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9891         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9892                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9893                              (match_operand:SI 3 "immediate_operand" "s")))))]
9894   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9895   "lwz %0,%2-%3(%1)"
9896   [(set_attr "type" "load")])
9898 (define_insn "load_toc_v4_PIC_3b"
9899   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9900         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9901                  (high:SI
9902                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9903                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9904   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9905   "addis %0,%1,%2-%3@ha")
9907 (define_insn "load_toc_v4_PIC_3c"
9908   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9909         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9910                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9911                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9912   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9913   "addi %0,%1,%2-%3@l")
9915 ;; If the TOC is shared over a translation unit, as happens with all
9916 ;; the kinds of PIC that we support, we need to restore the TOC
9917 ;; pointer only when jumping over units of translation.
9918 ;; On Darwin, we need to reload the picbase.
9920 (define_expand "builtin_setjmp_receiver"
9921   [(use (label_ref (match_operand 0 "" "")))]
9922   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9923    || (TARGET_TOC && TARGET_MINIMAL_TOC)
9924    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9925   "
9927 #if TARGET_MACHO
9928   if (DEFAULT_ABI == ABI_DARWIN)
9929     {
9930       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9931       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9932       rtx tmplabrtx;
9933       char tmplab[20];
9935       crtl->uses_pic_offset_table = 1;
9936       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9937                                   CODE_LABEL_NUMBER (operands[0]));
9938       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9940       emit_insn (gen_load_macho_picbase (tmplabrtx));
9941       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9942       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9943     }
9944   else
9945 #endif
9946     rs6000_emit_load_toc_table (FALSE);
9947   DONE;
9950 ;; Largetoc support
9951 (define_insn "*largetoc_high"
9952   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9953         (high:DI
9954           (unspec [(match_operand:DI 1 "" "")
9955                    (match_operand:DI 2 "gpc_reg_operand" "b")]
9956                   UNSPEC_TOCREL)))]
9957    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9958    "addis %0,%2,%1@toc@ha")
9960 (define_insn "*largetoc_high_aix<mode>"
9961   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9962         (high:P
9963           (unspec [(match_operand:P 1 "" "")
9964                    (match_operand:P 2 "gpc_reg_operand" "b")]
9965                   UNSPEC_TOCREL)))]
9966    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9967    "addis %0,%1@u(%2)")
9969 (define_insn "*largetoc_high_plus"
9970   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9971         (high:DI
9972           (plus:DI
9973             (unspec [(match_operand:DI 1 "" "")
9974                      (match_operand:DI 2 "gpc_reg_operand" "b")]
9975                     UNSPEC_TOCREL)
9976             (match_operand:DI 3 "add_cint_operand" "n"))))]
9977    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9978    "addis %0,%2,%1+%3@toc@ha")
9980 (define_insn "*largetoc_high_plus_aix<mode>"
9981   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9982         (high:P
9983           (plus:P
9984             (unspec [(match_operand:P 1 "" "")
9985                      (match_operand:P 2 "gpc_reg_operand" "b")]
9986                     UNSPEC_TOCREL)
9987             (match_operand:P 3 "add_cint_operand" "n"))))]
9988    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9989    "addis %0,%1+%3@u(%2)")
9991 (define_insn "*largetoc_low"
9992   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9993         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9994                    (match_operand:DI 2 "" "")))]
9995    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9996    "addi %0,%1,%2@l")
9998 (define_insn "*largetoc_low_aix<mode>"
9999   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10000         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10001                    (match_operand:P 2 "" "")))]
10002    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10003    "la %0,%2@l(%1)")
10005 (define_insn_and_split "*tocref<mode>"
10006   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10007         (match_operand:P 1 "small_toc_ref" "R"))]
10008    "TARGET_TOC"
10009    "la %0,%a1"
10010    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10011   [(set (match_dup 0) (high:P (match_dup 1)))
10012    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10014 ;; Elf specific ways of loading addresses for non-PIC code.
10015 ;; The output of this could be r0, but we make a very strong
10016 ;; preference for a base register because it will usually
10017 ;; be needed there.
10018 (define_insn "elf_high"
10019   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10020         (high:SI (match_operand 1 "" "")))]
10021   "TARGET_ELF && ! TARGET_64BIT"
10022   "lis %0,%1@ha")
10024 (define_insn "elf_low"
10025   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10026         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10027                    (match_operand 2 "" "")))]
10028    "TARGET_ELF && ! TARGET_64BIT"
10029    "la %0,%2@l(%1)")
10031 ;; Call and call_value insns
10032 (define_expand "call"
10033   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10034                     (match_operand 1 "" ""))
10035               (use (match_operand 2 "" ""))
10036               (clobber (reg:SI LR_REGNO))])]
10037   ""
10038   "
10040 #if TARGET_MACHO
10041   if (MACHOPIC_INDIRECT)
10042     operands[0] = machopic_indirect_call_target (operands[0]);
10043 #endif
10045   gcc_assert (GET_CODE (operands[0]) == MEM);
10046   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10048   operands[0] = XEXP (operands[0], 0);
10050   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10051     {
10052       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10053       DONE;
10054     }
10056   if (GET_CODE (operands[0]) != SYMBOL_REF
10057       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10058     {
10059       if (INTVAL (operands[2]) & CALL_LONG)
10060         operands[0] = rs6000_longcall_ref (operands[0]);
10062       switch (DEFAULT_ABI)
10063         {
10064         case ABI_V4:
10065         case ABI_DARWIN:
10066           operands[0] = force_reg (Pmode, operands[0]);
10067           break;
10069         default:
10070           gcc_unreachable ();
10071         }
10072     }
10075 (define_expand "call_value"
10076   [(parallel [(set (match_operand 0 "" "")
10077                    (call (mem:SI (match_operand 1 "address_operand" ""))
10078                          (match_operand 2 "" "")))
10079               (use (match_operand 3 "" ""))
10080               (clobber (reg:SI LR_REGNO))])]
10081   ""
10082   "
10084 #if TARGET_MACHO
10085   if (MACHOPIC_INDIRECT)
10086     operands[1] = machopic_indirect_call_target (operands[1]);
10087 #endif
10089   gcc_assert (GET_CODE (operands[1]) == MEM);
10090   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10092   operands[1] = XEXP (operands[1], 0);
10094   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10095     {
10096       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10097       DONE;
10098     }
10100   if (GET_CODE (operands[1]) != SYMBOL_REF
10101       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10102     {
10103       if (INTVAL (operands[3]) & CALL_LONG)
10104         operands[1] = rs6000_longcall_ref (operands[1]);
10106       switch (DEFAULT_ABI)
10107         {
10108         case ABI_V4:
10109         case ABI_DARWIN:
10110           operands[1] = force_reg (Pmode, operands[1]);
10111           break;
10113         default:
10114           gcc_unreachable ();
10115         }
10116     }
10119 ;; Call to function in current module.  No TOC pointer reload needed.
10120 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10121 ;; either the function was not prototyped, or it was prototyped as a
10122 ;; variable argument function.  It is > 0 if FP registers were passed
10123 ;; and < 0 if they were not.
10125 (define_insn "*call_local32"
10126   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10127          (match_operand 1 "" "g,g"))
10128    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10129    (clobber (reg:SI LR_REGNO))]
10130   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10131   "*
10133   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10134     output_asm_insn (\"crxor 6,6,6\", operands);
10136   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10137     output_asm_insn (\"creqv 6,6,6\", operands);
10139   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10141   [(set_attr "type" "branch")
10142    (set_attr "length" "4,8")])
10144 (define_insn "*call_local64"
10145   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10146          (match_operand 1 "" "g,g"))
10147    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10148    (clobber (reg:SI LR_REGNO))]
10149   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10150   "*
10152   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10153     output_asm_insn (\"crxor 6,6,6\", operands);
10155   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10156     output_asm_insn (\"creqv 6,6,6\", operands);
10158   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10160   [(set_attr "type" "branch")
10161    (set_attr "length" "4,8")])
10163 (define_insn "*call_value_local32"
10164   [(set (match_operand 0 "" "")
10165         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10166               (match_operand 2 "" "g,g")))
10167    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10168    (clobber (reg:SI LR_REGNO))]
10169   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10170   "*
10172   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10173     output_asm_insn (\"crxor 6,6,6\", operands);
10175   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10176     output_asm_insn (\"creqv 6,6,6\", operands);
10178   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10180   [(set_attr "type" "branch")
10181    (set_attr "length" "4,8")])
10184 (define_insn "*call_value_local64"
10185   [(set (match_operand 0 "" "")
10186         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10187               (match_operand 2 "" "g,g")))
10188    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10189    (clobber (reg:SI LR_REGNO))]
10190   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10191   "*
10193   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10194     output_asm_insn (\"crxor 6,6,6\", operands);
10196   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10197     output_asm_insn (\"creqv 6,6,6\", operands);
10199   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10201   [(set_attr "type" "branch")
10202    (set_attr "length" "4,8")])
10205 ;; A function pointer under System V is just a normal pointer
10206 ;; operands[0] is the function pointer
10207 ;; operands[1] is the stack size to clean up
10208 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10209 ;; which indicates how to set cr1
10211 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10212   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10213          (match_operand 1 "" "g,g,g,g"))
10214    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10215    (clobber (reg:SI LR_REGNO))]
10216   "DEFAULT_ABI == ABI_V4
10217    || DEFAULT_ABI == ABI_DARWIN"
10219   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10220     output_asm_insn ("crxor 6,6,6", operands);
10222   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10223     output_asm_insn ("creqv 6,6,6", operands);
10225   return "b%T0l";
10227   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10228    (set_attr "length" "4,4,8,8")])
10230 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10231   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10232          (match_operand 1 "" "g,g"))
10233    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10234    (clobber (reg:SI LR_REGNO))]
10235   "(DEFAULT_ABI == ABI_DARWIN
10236    || (DEFAULT_ABI == ABI_V4
10237        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10239   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10240     output_asm_insn ("crxor 6,6,6", operands);
10242   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10243     output_asm_insn ("creqv 6,6,6", operands);
10245 #if TARGET_MACHO
10246   return output_call(insn, operands, 0, 2);
10247 #else
10248   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10249     {
10250       gcc_assert (!TARGET_SECURE_PLT);
10251       return "bl %z0@plt";
10252     }
10253   else
10254     return "bl %z0";
10255 #endif
10257   "DEFAULT_ABI == ABI_V4
10258    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10259    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10260   [(parallel [(call (mem:SI (match_dup 0))
10261                     (match_dup 1))
10262               (use (match_dup 2))
10263               (use (match_dup 3))
10264               (clobber (reg:SI LR_REGNO))])]
10266   operands[3] = pic_offset_table_rtx;
10268   [(set_attr "type" "branch,branch")
10269    (set_attr "length" "4,8")])
10271 (define_insn "*call_nonlocal_sysv_secure<mode>"
10272   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10273          (match_operand 1 "" "g,g"))
10274    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10275    (use (match_operand:SI 3 "register_operand" "r,r"))
10276    (clobber (reg:SI LR_REGNO))]
10277   "(DEFAULT_ABI == ABI_V4
10278     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10279     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10281   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10282     output_asm_insn ("crxor 6,6,6", operands);
10284   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10285     output_asm_insn ("creqv 6,6,6", operands);
10287   if (flag_pic == 2)
10288     /* The magic 32768 offset here and in the other sysv call insns
10289        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10290        See sysv4.h:toc_section.  */
10291     return "bl %z0+32768@plt";
10292   else
10293     return "bl %z0@plt";
10295   [(set_attr "type" "branch,branch")
10296    (set_attr "length" "4,8")])
10298 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10299   [(set (match_operand 0 "" "")
10300         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10301               (match_operand 2 "" "g,g,g,g")))
10302    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10303    (clobber (reg:SI LR_REGNO))]
10304   "DEFAULT_ABI == ABI_V4
10305    || DEFAULT_ABI == ABI_DARWIN"
10307   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10308     output_asm_insn ("crxor 6,6,6", operands);
10310   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10311     output_asm_insn ("creqv 6,6,6", operands);
10313   return "b%T1l";
10315   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10316    (set_attr "length" "4,4,8,8")])
10318 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10319   [(set (match_operand 0 "" "")
10320         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10321               (match_operand 2 "" "g,g")))
10322    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10323    (clobber (reg:SI LR_REGNO))]
10324   "(DEFAULT_ABI == ABI_DARWIN
10325    || (DEFAULT_ABI == ABI_V4
10326        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10328   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10329     output_asm_insn ("crxor 6,6,6", operands);
10331   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10332     output_asm_insn ("creqv 6,6,6", operands);
10334 #if TARGET_MACHO
10335   return output_call(insn, operands, 1, 3);
10336 #else
10337   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10338     {
10339       gcc_assert (!TARGET_SECURE_PLT);
10340       return "bl %z1@plt";
10341     }
10342   else
10343     return "bl %z1";
10344 #endif
10346   "DEFAULT_ABI == ABI_V4
10347    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10348    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10349   [(parallel [(set (match_dup 0)
10350                    (call (mem:SI (match_dup 1))
10351                          (match_dup 2)))
10352               (use (match_dup 3))
10353               (use (match_dup 4))
10354               (clobber (reg:SI LR_REGNO))])]
10356   operands[4] = pic_offset_table_rtx;
10358   [(set_attr "type" "branch,branch")
10359    (set_attr "length" "4,8")])
10361 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10362   [(set (match_operand 0 "" "")
10363         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10364               (match_operand 2 "" "g,g")))
10365    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10366    (use (match_operand:SI 4 "register_operand" "r,r"))
10367    (clobber (reg:SI LR_REGNO))]
10368   "(DEFAULT_ABI == ABI_V4
10369     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10370     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10372   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10373     output_asm_insn ("crxor 6,6,6", operands);
10375   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10376     output_asm_insn ("creqv 6,6,6", operands);
10378   if (flag_pic == 2)
10379     return "bl %z1+32768@plt";
10380   else
10381     return "bl %z1@plt";
10383   [(set_attr "type" "branch,branch")
10384    (set_attr "length" "4,8")])
10387 ;; Call to AIX abi function in the same module.
10389 (define_insn "*call_local_aix<mode>"
10390   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10391          (match_operand 1 "" "g"))
10392    (clobber (reg:P LR_REGNO))]
10393   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10394   "bl %z0"
10395   [(set_attr "type" "branch")
10396    (set_attr "length" "4")])
10398 (define_insn "*call_value_local_aix<mode>"
10399   [(set (match_operand 0 "" "")
10400         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10401               (match_operand 2 "" "g")))
10402    (clobber (reg:P LR_REGNO))]
10403   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10404   "bl %z1"
10405   [(set_attr "type" "branch")
10406    (set_attr "length" "4")])
10408 ;; Call to AIX abi function which may be in another module.
10409 ;; Restore the TOC pointer (r2) after the call.
10411 (define_insn "*call_nonlocal_aix<mode>"
10412   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10413          (match_operand 1 "" "g"))
10414    (clobber (reg:P LR_REGNO))]
10415   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10416   "bl %z0\;nop"
10417   [(set_attr "type" "branch")
10418    (set_attr "length" "8")])
10420 (define_insn "*call_value_nonlocal_aix<mode>"
10421   [(set (match_operand 0 "" "")
10422         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10423               (match_operand 2 "" "g")))
10424    (clobber (reg:P LR_REGNO))]
10425   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10426   "bl %z1\;nop"
10427   [(set_attr "type" "branch")
10428    (set_attr "length" "8")])
10430 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10431 ;; Operand0 is the addresss of the function to call
10432 ;; Operand2 is the location in the function descriptor to load r2 from
10433 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10435 (define_insn "*call_indirect_aix<mode>"
10436   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10437          (match_operand 1 "" "g,g"))
10438    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10439    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10440    (clobber (reg:P LR_REGNO))]
10441   "DEFAULT_ABI == ABI_AIX"
10442   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10443   [(set_attr "type" "jmpreg")
10444    (set_attr "length" "12")])
10446 (define_insn "*call_value_indirect_aix<mode>"
10447   [(set (match_operand 0 "" "")
10448         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10449               (match_operand 2 "" "g,g")))
10450    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10451    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10452    (clobber (reg:P LR_REGNO))]
10453   "DEFAULT_ABI == ABI_AIX"
10454   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10455   [(set_attr "type" "jmpreg")
10456    (set_attr "length" "12")])
10458 ;; Call to indirect functions with the ELFv2 ABI.
10459 ;; Operand0 is the addresss of the function to call
10460 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10462 (define_insn "*call_indirect_elfv2<mode>"
10463   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10464          (match_operand 1 "" "g,g"))
10465    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10466    (clobber (reg:P LR_REGNO))]
10467   "DEFAULT_ABI == ABI_ELFv2"
10468   "b%T0l\;<ptrload> 2,%2(1)"
10469   [(set_attr "type" "jmpreg")
10470    (set_attr "length" "8")])
10472 (define_insn "*call_value_indirect_elfv2<mode>"
10473   [(set (match_operand 0 "" "")
10474         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10475               (match_operand 2 "" "g,g")))
10476    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10477    (clobber (reg:P LR_REGNO))]
10478   "DEFAULT_ABI == ABI_ELFv2"
10479   "b%T1l\;<ptrload> 2,%3(1)"
10480   [(set_attr "type" "jmpreg")
10481    (set_attr "length" "8")])
10484 ;; Call subroutine returning any type.
10485 (define_expand "untyped_call"
10486   [(parallel [(call (match_operand 0 "" "")
10487                     (const_int 0))
10488               (match_operand 1 "" "")
10489               (match_operand 2 "" "")])]
10490   ""
10491   "
10493   int i;
10495   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10497   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10498     {
10499       rtx set = XVECEXP (operands[2], 0, i);
10500       emit_move_insn (SET_DEST (set), SET_SRC (set));
10501     }
10503   /* The optimizer does not know that the call sets the function value
10504      registers we stored in the result block.  We avoid problems by
10505      claiming that all hard registers are used and clobbered at this
10506      point.  */
10507   emit_insn (gen_blockage ());
10509   DONE;
10512 ;; sibling call patterns
10513 (define_expand "sibcall"
10514   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10515                     (match_operand 1 "" ""))
10516               (use (match_operand 2 "" ""))
10517               (use (reg:SI LR_REGNO))
10518               (simple_return)])]
10519   ""
10520   "
10522 #if TARGET_MACHO
10523   if (MACHOPIC_INDIRECT)
10524     operands[0] = machopic_indirect_call_target (operands[0]);
10525 #endif
10527   gcc_assert (GET_CODE (operands[0]) == MEM);
10528   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10530   operands[0] = XEXP (operands[0], 0);
10532   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10533     {
10534       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10535       DONE;
10536     }
10539 (define_expand "sibcall_value"
10540   [(parallel [(set (match_operand 0 "register_operand" "")
10541                 (call (mem:SI (match_operand 1 "address_operand" ""))
10542                       (match_operand 2 "" "")))
10543               (use (match_operand 3 "" ""))
10544               (use (reg:SI LR_REGNO))
10545               (simple_return)])]
10546   ""
10547   "
10549 #if TARGET_MACHO
10550   if (MACHOPIC_INDIRECT)
10551     operands[1] = machopic_indirect_call_target (operands[1]);
10552 #endif
10554   gcc_assert (GET_CODE (operands[1]) == MEM);
10555   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10557   operands[1] = XEXP (operands[1], 0);
10559   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10560     {
10561       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10562       DONE;
10563     }
10566 ;; this and similar patterns must be marked as using LR, otherwise
10567 ;; dataflow will try to delete the store into it.  This is true
10568 ;; even when the actual reg to jump to is in CTR, when LR was
10569 ;; saved and restored around the PIC-setting BCL.
10570 (define_insn "*sibcall_local32"
10571   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10572          (match_operand 1 "" "g,g"))
10573    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10574    (use (reg:SI LR_REGNO))
10575    (simple_return)]
10576   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10577   "*
10579   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10580     output_asm_insn (\"crxor 6,6,6\", operands);
10582   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10583     output_asm_insn (\"creqv 6,6,6\", operands);
10585   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10587   [(set_attr "type" "branch")
10588    (set_attr "length" "4,8")])
10590 (define_insn "*sibcall_local64"
10591   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10592          (match_operand 1 "" "g,g"))
10593    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10594    (use (reg:SI LR_REGNO))
10595    (simple_return)]
10596   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10597   "*
10599   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10600     output_asm_insn (\"crxor 6,6,6\", operands);
10602   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10603     output_asm_insn (\"creqv 6,6,6\", operands);
10605   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10607   [(set_attr "type" "branch")
10608    (set_attr "length" "4,8")])
10610 (define_insn "*sibcall_value_local32"
10611   [(set (match_operand 0 "" "")
10612         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10613               (match_operand 2 "" "g,g")))
10614    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10615    (use (reg:SI LR_REGNO))
10616    (simple_return)]
10617   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10618   "*
10620   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10621     output_asm_insn (\"crxor 6,6,6\", operands);
10623   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10624     output_asm_insn (\"creqv 6,6,6\", operands);
10626   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10628   [(set_attr "type" "branch")
10629    (set_attr "length" "4,8")])
10631 (define_insn "*sibcall_value_local64"
10632   [(set (match_operand 0 "" "")
10633         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10634               (match_operand 2 "" "g,g")))
10635    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10636    (use (reg:SI LR_REGNO))
10637    (simple_return)]
10638   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10639   "*
10641   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10642     output_asm_insn (\"crxor 6,6,6\", operands);
10644   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10645     output_asm_insn (\"creqv 6,6,6\", operands);
10647   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10649   [(set_attr "type" "branch")
10650    (set_attr "length" "4,8")])
10652 (define_insn "*sibcall_nonlocal_sysv<mode>"
10653   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10654          (match_operand 1 "" ""))
10655    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10656    (use (reg:SI LR_REGNO))
10657    (simple_return)]
10658   "(DEFAULT_ABI == ABI_DARWIN
10659     || DEFAULT_ABI == ABI_V4)
10660    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10661   "*
10663   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10664     output_asm_insn (\"crxor 6,6,6\", operands);
10666   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10667     output_asm_insn (\"creqv 6,6,6\", operands);
10669   if (which_alternative >= 2)
10670     return \"b%T0\";
10671   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10672     {
10673       gcc_assert (!TARGET_SECURE_PLT);
10674       return \"b %z0@plt\";
10675     }
10676   else
10677     return \"b %z0\";
10679   [(set_attr "type" "branch")
10680    (set_attr "length" "4,8,4,8")])
10682 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10683   [(set (match_operand 0 "" "")
10684         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10685               (match_operand 2 "" "")))
10686    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10687    (use (reg:SI LR_REGNO))
10688    (simple_return)]
10689   "(DEFAULT_ABI == ABI_DARWIN
10690     || DEFAULT_ABI == ABI_V4)
10691    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10692   "*
10694   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10695     output_asm_insn (\"crxor 6,6,6\", operands);
10697   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10698     output_asm_insn (\"creqv 6,6,6\", operands);
10700   if (which_alternative >= 2)
10701     return \"b%T1\";
10702   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10703     {
10704       gcc_assert (!TARGET_SECURE_PLT);
10705       return \"b %z1@plt\";
10706     }
10707   else
10708     return \"b %z1\";
10710   [(set_attr "type" "branch")
10711    (set_attr "length" "4,8,4,8")])
10713 ;; AIX ABI sibling call patterns.
10715 (define_insn "*sibcall_aix<mode>"
10716   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10717          (match_operand 1 "" "g,g"))
10718    (simple_return)]
10719   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10720   "@
10721    b %z0
10722    b%T0"
10723   [(set_attr "type" "branch")
10724    (set_attr "length" "4")])
10726 (define_insn "*sibcall_value_aix<mode>"
10727   [(set (match_operand 0 "" "")
10728         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10729               (match_operand 2 "" "g,g")))
10730    (simple_return)]
10731   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10732   "@
10733    b %z1
10734    b%T1"
10735   [(set_attr "type" "branch")
10736    (set_attr "length" "4")])
10738 (define_expand "sibcall_epilogue"
10739   [(use (const_int 0))]
10740   ""
10742   if (!TARGET_SCHED_PROLOG)
10743     emit_insn (gen_blockage ());
10744   rs6000_emit_epilogue (TRUE);
10745   DONE;
10748 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10749 ;; all of memory.  This blocks insns from being moved across this point.
10751 (define_insn "blockage"
10752   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10753   ""
10754   "")
10756 (define_expand "probe_stack_address"
10757   [(use (match_operand 0 "address_operand"))]
10758   ""
10760   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10761   MEM_VOLATILE_P (operands[0]) = 1;
10763   if (TARGET_64BIT)
10764     emit_insn (gen_probe_stack_di (operands[0]));
10765   else
10766     emit_insn (gen_probe_stack_si (operands[0]));
10767   DONE;
10770 (define_insn "probe_stack_<mode>"
10771   [(set (match_operand:P 0 "memory_operand" "=m")
10772         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10773   ""
10775   operands[1] = gen_rtx_REG (Pmode, 0);
10776   return "st<wd>%U0%X0 %1,%0";
10778   [(set_attr "type" "store")
10779    (set (attr "update")
10780         (if_then_else (match_operand 0 "update_address_mem")
10781                       (const_string "yes")
10782                       (const_string "no")))
10783    (set (attr "indexed")
10784         (if_then_else (match_operand 0 "indexed_address_mem")
10785                       (const_string "yes")
10786                       (const_string "no")))
10787    (set_attr "length" "4")])
10789 (define_insn "probe_stack_range<P:mode>"
10790   [(set (match_operand:P 0 "register_operand" "=r")
10791         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10792                             (match_operand:P 2 "register_operand" "r")]
10793                            UNSPECV_PROBE_STACK_RANGE))]
10794   ""
10795   "* return output_probe_stack_range (operands[0], operands[2]);"
10796   [(set_attr "type" "three")])
10798 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10799 ;; signed & unsigned, and one type of branch.
10801 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10802 ;; insns, and branches.
10804 (define_expand "cbranch<mode>4"
10805   [(use (match_operator 0 "rs6000_cbranch_operator"
10806          [(match_operand:GPR 1 "gpc_reg_operand" "")
10807           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10808    (use (match_operand 3 ""))]
10809   ""
10810   "
10812   /* Take care of the possibility that operands[2] might be negative but
10813      this might be a logical operation.  That insn doesn't exist.  */
10814   if (GET_CODE (operands[2]) == CONST_INT
10815       && INTVAL (operands[2]) < 0)
10816     {
10817       operands[2] = force_reg (<MODE>mode, operands[2]);
10818       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10819                                     GET_MODE (operands[0]),
10820                                     operands[1], operands[2]);
10821    }
10823   rs6000_emit_cbranch (<MODE>mode, operands);
10824   DONE;
10827 (define_expand "cbranch<mode>4"
10828   [(use (match_operator 0 "rs6000_cbranch_operator"
10829          [(match_operand:FP 1 "gpc_reg_operand" "")
10830           (match_operand:FP 2 "gpc_reg_operand" "")]))
10831    (use (match_operand 3 ""))]
10832   ""
10833   "
10835   rs6000_emit_cbranch (<MODE>mode, operands);
10836   DONE;
10839 (define_expand "cstore<mode>4_signed"
10840   [(use (match_operator 1 "signed_comparison_operator"
10841          [(match_operand:P 2 "gpc_reg_operand")
10842           (match_operand:P 3 "gpc_reg_operand")]))
10843    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10844   ""
10846   enum rtx_code cond_code = GET_CODE (operands[1]);
10848   rtx op0 = operands[0];
10849   rtx op1 = operands[2];
10850   rtx op2 = operands[3];
10852   if (cond_code == GE || cond_code == LT)
10853     {
10854       cond_code = swap_condition (cond_code);
10855       std::swap (op1, op2);
10856     }
10858   rtx tmp1 = gen_reg_rtx (<MODE>mode);
10859   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10860   rtx tmp3 = gen_reg_rtx (<MODE>mode);
10862   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10863   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10864   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10866   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10868   if (cond_code == LE)
10869     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10870   else
10871     {
10872       rtx tmp4 = gen_reg_rtx (<MODE>mode);
10873       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10874       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10875     }
10877   DONE;
10880 (define_expand "cstore<mode>4_unsigned"
10881   [(use (match_operator 1 "unsigned_comparison_operator"
10882          [(match_operand:P 2 "gpc_reg_operand")
10883           (match_operand:P 3 "reg_or_short_operand")]))
10884    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10885   ""
10887   enum rtx_code cond_code = GET_CODE (operands[1]);
10889   rtx op0 = operands[0];
10890   rtx op1 = operands[2];
10891   rtx op2 = operands[3];
10893   if (cond_code == GEU || cond_code == LTU)
10894     {
10895       cond_code = swap_condition (cond_code);
10896       std::swap (op1, op2);
10897     }
10899   if (!gpc_reg_operand (op1, <MODE>mode))
10900     op1 = force_reg (<MODE>mode, op1);
10901   if (!reg_or_short_operand (op2, <MODE>mode))
10902     op2 = force_reg (<MODE>mode, op2);
10904   rtx tmp = gen_reg_rtx (<MODE>mode);
10905   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10907   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10908   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10910   if (cond_code == LEU)
10911     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10912   else
10913     emit_insn (gen_neg<mode>2 (op0, tmp2));
10915   DONE;
10918 (define_expand "cstore_si_as_di"
10919   [(use (match_operator 1 "unsigned_comparison_operator"
10920          [(match_operand:SI 2 "gpc_reg_operand")
10921           (match_operand:SI 3 "reg_or_short_operand")]))
10922    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10923   ""
10925   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10926   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10928   operands[2] = force_reg (SImode, operands[2]);
10929   operands[3] = force_reg (SImode, operands[3]);
10930   rtx op1 = gen_reg_rtx (DImode);
10931   rtx op2 = gen_reg_rtx (DImode);
10932   convert_move (op1, operands[2], uns_flag);
10933   convert_move (op2, operands[3], uns_flag);
10935   if (cond_code == GT || cond_code == LE)
10936     {
10937       cond_code = swap_condition (cond_code);
10938       std::swap (op1, op2);
10939     }
10941   rtx tmp = gen_reg_rtx (DImode);
10942   rtx tmp2 = gen_reg_rtx (DImode);
10943   emit_insn (gen_subdi3 (tmp, op1, op2));
10944   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10946   rtx tmp3;
10947   switch (cond_code)
10948     {
10949     default:
10950       gcc_unreachable ();
10951     case LT:
10952       tmp3 = tmp2;
10953       break;
10954     case GE:
10955       tmp3 = gen_reg_rtx (DImode);
10956       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10957       break;
10958     }
10960   convert_move (operands[0], tmp3, 1);
10962   DONE;
10965 (define_expand "cstore<mode>4_signed_imm"
10966   [(use (match_operator 1 "signed_comparison_operator"
10967          [(match_operand:GPR 2 "gpc_reg_operand")
10968           (match_operand:GPR 3 "immediate_operand")]))
10969    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10970   ""
10972   bool invert = false;
10974   enum rtx_code cond_code = GET_CODE (operands[1]);
10976   rtx op0 = operands[0];
10977   rtx op1 = operands[2];
10978   HOST_WIDE_INT val = INTVAL (operands[3]);
10980   if (cond_code == GE || cond_code == GT)
10981     {
10982       cond_code = reverse_condition (cond_code);
10983       invert = true;
10984     }
10986   if (cond_code == LE)
10987     val++;
10989   rtx tmp = gen_reg_rtx (<MODE>mode);
10990   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10991   rtx x = gen_reg_rtx (<MODE>mode);
10992   if (val < 0)
10993     emit_insn (gen_and<mode>3 (x, op1, tmp));
10994   else
10995     emit_insn (gen_ior<mode>3 (x, op1, tmp));
10997   if (invert)
10998     {
10999       rtx tmp = gen_reg_rtx (<MODE>mode);
11000       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11001       x = tmp;
11002     }
11004   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11005   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11007   DONE;
11010 (define_expand "cstore<mode>4_unsigned_imm"
11011   [(use (match_operator 1 "unsigned_comparison_operator"
11012          [(match_operand:GPR 2 "gpc_reg_operand")
11013           (match_operand:GPR 3 "immediate_operand")]))
11014    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11015   ""
11017   bool invert = false;
11019   enum rtx_code cond_code = GET_CODE (operands[1]);
11021   rtx op0 = operands[0];
11022   rtx op1 = operands[2];
11023   HOST_WIDE_INT val = INTVAL (operands[3]);
11025   if (cond_code == GEU || cond_code == GTU)
11026     {
11027       cond_code = reverse_condition (cond_code);
11028       invert = true;
11029     }
11031   if (cond_code == LEU)
11032     val++;
11034   rtx tmp = gen_reg_rtx (<MODE>mode);
11035   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11036   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11037   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11038   rtx x = gen_reg_rtx (<MODE>mode);
11039   if (val < 0)
11040     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11041   else
11042     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11044   if (invert)
11045     {
11046       rtx tmp = gen_reg_rtx (<MODE>mode);
11047       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11048       x = tmp;
11049     }
11051   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11052   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11054   DONE;
11057 (define_expand "cstore<mode>4"
11058   [(use (match_operator 1 "rs6000_cbranch_operator"
11059          [(match_operand:GPR 2 "gpc_reg_operand")
11060           (match_operand:GPR 3 "reg_or_short_operand")]))
11061    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11062   ""
11064   /* Use ISEL if the user asked for it.  */
11065   if (TARGET_ISEL)
11066     rs6000_emit_sISEL (<MODE>mode, operands);
11068   /* Expanding EQ and NE directly to some machine instructions does not help
11069      but does hurt combine.  So don't.  */
11070   else if (GET_CODE (operands[1]) == EQ)
11071     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11072   else if (<MODE>mode == Pmode
11073            && GET_CODE (operands[1]) == NE)
11074     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11075   else if (GET_CODE (operands[1]) == NE)
11076     {
11077       rtx tmp = gen_reg_rtx (<MODE>mode);
11078       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11079       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11080     }
11082   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11083      etc. combinations magically work out just right.  */
11084   else if (<MODE>mode == Pmode
11085            && unsigned_comparison_operator (operands[1], VOIDmode))
11086     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11087                                            operands[2], operands[3]));
11089   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11090   else if (<MODE>mode == SImode && Pmode == DImode)
11091     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11092                                     operands[2], operands[3]));
11094   /* For signed comparisons against a constant, we can do some simple
11095      bit-twiddling.  */
11096   else if (signed_comparison_operator (operands[1], VOIDmode)
11097            && CONST_INT_P (operands[3]))
11098     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11099                                              operands[2], operands[3]));
11101   /* And similarly for unsigned comparisons.  */
11102   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11103            && CONST_INT_P (operands[3]))
11104     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11105                                                operands[2], operands[3]));
11107   /* We also do not want to use mfcr for signed comparisons.  */
11108   else if (<MODE>mode == Pmode
11109            && signed_comparison_operator (operands[1], VOIDmode))
11110     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11111                                          operands[2], operands[3]));
11113   /* Everything else, use the mfcr brute force.  */
11114   else
11115     rs6000_emit_sCOND (<MODE>mode, operands);
11117   DONE;
11120 (define_expand "cstore<mode>4"
11121   [(use (match_operator 1 "rs6000_cbranch_operator"
11122          [(match_operand:FP 2 "gpc_reg_operand")
11123           (match_operand:FP 3 "gpc_reg_operand")]))
11124    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11125   ""
11127   rs6000_emit_sCOND (<MODE>mode, operands);
11128   DONE;
11132 (define_expand "stack_protect_set"
11133   [(match_operand 0 "memory_operand" "")
11134    (match_operand 1 "memory_operand" "")]
11135   ""
11137 #ifdef TARGET_THREAD_SSP_OFFSET
11138   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11139   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11140   operands[1] = gen_rtx_MEM (Pmode, addr);
11141 #endif
11142   if (TARGET_64BIT)
11143     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11144   else
11145     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11146   DONE;
11149 (define_insn "stack_protect_setsi"
11150   [(set (match_operand:SI 0 "memory_operand" "=m")
11151         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11152    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11153   "TARGET_32BIT"
11154   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11155   [(set_attr "type" "three")
11156    (set_attr "length" "12")])
11158 (define_insn "stack_protect_setdi"
11159   [(set (match_operand:DI 0 "memory_operand" "=Y")
11160         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11161    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11162   "TARGET_64BIT"
11163   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11164   [(set_attr "type" "three")
11165    (set_attr "length" "12")])
11167 (define_expand "stack_protect_test"
11168   [(match_operand 0 "memory_operand" "")
11169    (match_operand 1 "memory_operand" "")
11170    (match_operand 2 "" "")]
11171   ""
11173   rtx test, op0, op1;
11174 #ifdef TARGET_THREAD_SSP_OFFSET
11175   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11176   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11177   operands[1] = gen_rtx_MEM (Pmode, addr);
11178 #endif
11179   op0 = operands[0];
11180   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11181   test = gen_rtx_EQ (VOIDmode, op0, op1);
11182   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11183   DONE;
11186 (define_insn "stack_protect_testsi"
11187   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11188         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11189                       (match_operand:SI 2 "memory_operand" "m,m")]
11190                      UNSPEC_SP_TEST))
11191    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11192    (clobber (match_scratch:SI 3 "=&r,&r"))]
11193   "TARGET_32BIT"
11194   "@
11195    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11196    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11197   [(set_attr "length" "16,20")])
11199 (define_insn "stack_protect_testdi"
11200   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11201         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11202                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11203                      UNSPEC_SP_TEST))
11204    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11205    (clobber (match_scratch:DI 3 "=&r,&r"))]
11206   "TARGET_64BIT"
11207   "@
11208    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11209    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11210   [(set_attr "length" "16,20")])
11213 ;; Here are the actual compare insns.
11214 (define_insn "*cmp<mode>_signed"
11215   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11216         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11217                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11218   ""
11219   "cmp<wd>%I2 %0,%1,%2"
11220   [(set_attr "type" "cmp")])
11222 (define_insn "*cmp<mode>_unsigned"
11223   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11224         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11225                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11226   ""
11227   "cmpl<wd>%I2 %0,%1,%2"
11228   [(set_attr "type" "cmp")])
11230 ;; If we are comparing a register for equality with a large constant,
11231 ;; we can do this with an XOR followed by a compare.  But this is profitable
11232 ;; only if the large constant is only used for the comparison (and in this
11233 ;; case we already have a register to reuse as scratch).
11235 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11236 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11238 (define_peephole2
11239   [(set (match_operand:SI 0 "register_operand")
11240         (match_operand:SI 1 "logical_const_operand" ""))
11241    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11242                        [(match_dup 0)
11243                         (match_operand:SI 2 "logical_const_operand" "")]))
11244    (set (match_operand:CC 4 "cc_reg_operand" "")
11245         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11246                     (match_dup 0)))
11247    (set (pc)
11248         (if_then_else (match_operator 6 "equality_operator"
11249                        [(match_dup 4) (const_int 0)])
11250                       (match_operand 7 "" "")
11251                       (match_operand 8 "" "")))]
11252   "peep2_reg_dead_p (3, operands[0])
11253    && peep2_reg_dead_p (4, operands[4])
11254    && REGNO (operands[0]) != REGNO (operands[5])"
11255  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11256   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11257   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11260   /* Get the constant we are comparing against, and see what it looks like
11261      when sign-extended from 16 to 32 bits.  Then see what constant we could
11262      XOR with SEXTC to get the sign-extended value.  */
11263   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11264                                               SImode,
11265                                               operands[1], operands[2]);
11266   HOST_WIDE_INT c = INTVAL (cnst);
11267   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11268   HOST_WIDE_INT xorv = c ^ sextc;
11270   operands[9] = GEN_INT (xorv);
11271   operands[10] = GEN_INT (sextc);
11274 ;; The following two insns don't exist as single insns, but if we provide
11275 ;; them, we can swap an add and compare, which will enable us to overlap more
11276 ;; of the required delay between a compare and branch.  We generate code for
11277 ;; them by splitting.
11279 (define_insn ""
11280   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11281         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11282                     (match_operand:SI 2 "short_cint_operand" "i")))
11283    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11284         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11285   ""
11286   "#"
11287   [(set_attr "length" "8")])
11289 (define_insn ""
11290   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11291         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11292                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11293    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11294         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11295   ""
11296   "#"
11297   [(set_attr "length" "8")])
11299 (define_split
11300   [(set (match_operand:CC 3 "cc_reg_operand" "")
11301         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11302                     (match_operand:SI 2 "short_cint_operand" "")))
11303    (set (match_operand:SI 0 "gpc_reg_operand" "")
11304         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11305   ""
11306   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11307    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11309 (define_split
11310   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11311         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11312                        (match_operand:SI 2 "u_short_cint_operand" "")))
11313    (set (match_operand:SI 0 "gpc_reg_operand" "")
11314         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11315   ""
11316   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11317    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11319 ;; Only need to compare second words if first words equal
11320 (define_insn "*cmp<mode>_internal1"
11321   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11322         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11323                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11324   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11325    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11326   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11327   [(set_attr "type" "fpcompare")
11328    (set_attr "length" "12")])
11330 (define_insn_and_split "*cmp<mode>_internal2"
11331   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11332         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11333                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11334     (clobber (match_scratch:DF 3 "=d"))
11335     (clobber (match_scratch:DF 4 "=d"))
11336     (clobber (match_scratch:DF 5 "=d"))
11337     (clobber (match_scratch:DF 6 "=d"))
11338     (clobber (match_scratch:DF 7 "=d"))
11339     (clobber (match_scratch:DF 8 "=d"))
11340     (clobber (match_scratch:DF 9 "=d"))
11341     (clobber (match_scratch:DF 10 "=d"))
11342     (clobber (match_scratch:GPR 11 "=b"))]
11343   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11344    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11345   "#"
11346   "&& reload_completed"
11347   [(set (match_dup 3) (match_dup 14))
11348    (set (match_dup 4) (match_dup 15))
11349    (set (match_dup 9) (abs:DF (match_dup 5)))
11350    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11351    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11352                            (label_ref (match_dup 12))
11353                            (pc)))
11354    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11355    (set (pc) (label_ref (match_dup 13)))
11356    (match_dup 12)
11357    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11358    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11359    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11360    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11361    (match_dup 13)]
11363   REAL_VALUE_TYPE rv;
11364   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11365   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11367   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11368   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11369   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11370   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11371   operands[12] = gen_label_rtx ();
11372   operands[13] = gen_label_rtx ();
11373   real_inf (&rv);
11374   operands[14] = force_const_mem (DFmode,
11375                                   const_double_from_real_value (rv, DFmode));
11376   operands[15] = force_const_mem (DFmode,
11377                                   const_double_from_real_value (dconst0,
11378                                                                 DFmode));
11379   if (TARGET_TOC)
11380     {
11381       rtx tocref;
11382       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11383       operands[14] = gen_const_mem (DFmode, tocref);
11384       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11385       operands[15] = gen_const_mem (DFmode, tocref);
11386       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11387       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11388     }
11391 ;; Now we have the scc insns.  We can do some combinations because of the
11392 ;; way the machine works.
11394 ;; Note that this is probably faster if we can put an insn between the
11395 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11396 ;; cases the insns below which don't use an intermediate CR field will
11397 ;; be used instead.
11398 (define_insn ""
11399   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11400         (match_operator:SI 1 "scc_comparison_operator"
11401                            [(match_operand 2 "cc_reg_operand" "y")
11402                             (const_int 0)]))]
11403   ""
11404   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11405   [(set (attr "type")
11406      (cond [(match_test "TARGET_MFCRF")
11407                 (const_string "mfcrf")
11408            ]
11409         (const_string "mfcr")))
11410    (set_attr "length" "8")])
11412 ;; Same as above, but get the GT bit.
11413 (define_insn "move_from_CR_gt_bit"
11414   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11415         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11416   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11417   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11418   [(set_attr "type" "mfcr")
11419    (set_attr "length" "8")])
11421 ;; Same as above, but get the OV/ORDERED bit.
11422 (define_insn "move_from_CR_ov_bit"
11423   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11424         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11425                    UNSPEC_MV_CR_OV))]
11426   "TARGET_ISEL"
11427   "mfcr %0\;rlwinm %0,%0,%t1,1"
11428   [(set_attr "type" "mfcr")
11429    (set_attr "length" "8")])
11431 (define_insn ""
11432   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11433         (match_operator:DI 1 "scc_comparison_operator"
11434                            [(match_operand 2 "cc_reg_operand" "y")
11435                             (const_int 0)]))]
11436   "TARGET_POWERPC64"
11437   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11438   [(set (attr "type")
11439      (cond [(match_test "TARGET_MFCRF")
11440                 (const_string "mfcrf")
11441            ]
11442         (const_string "mfcr")))
11443    (set_attr "length" "8")])
11445 (define_insn ""
11446   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11447         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11448                                        [(match_operand 2 "cc_reg_operand" "y,y")
11449                                         (const_int 0)])
11450                     (const_int 0)))
11451    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11452         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11453   "TARGET_32BIT"
11454   "@
11455    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11456    #"
11457   [(set_attr "type" "shift")
11458    (set_attr "dot" "yes")
11459    (set_attr "length" "8,16")])
11461 (define_split
11462   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11463         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11464                                        [(match_operand 2 "cc_reg_operand" "")
11465                                         (const_int 0)])
11466                     (const_int 0)))
11467    (set (match_operand:SI 3 "gpc_reg_operand" "")
11468         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11469   "TARGET_32BIT && reload_completed"
11470   [(set (match_dup 3)
11471         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11472    (set (match_dup 0)
11473         (compare:CC (match_dup 3)
11474                     (const_int 0)))]
11475   "")
11477 (define_insn ""
11478   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11479         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11480                                       [(match_operand 2 "cc_reg_operand" "y")
11481                                        (const_int 0)])
11482                    (match_operand:SI 3 "const_int_operand" "n")))]
11483   ""
11484   "*
11486   int is_bit = ccr_bit (operands[1], 1);
11487   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11488   int count;
11490   if (is_bit >= put_bit)
11491     count = is_bit - put_bit;
11492   else
11493     count = 32 - (put_bit - is_bit);
11495   operands[4] = GEN_INT (count);
11496   operands[5] = GEN_INT (put_bit);
11498   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11500   [(set (attr "type")
11501      (cond [(match_test "TARGET_MFCRF")
11502                 (const_string "mfcrf")
11503            ]
11504         (const_string "mfcr")))
11505    (set_attr "length" "8")])
11507 (define_insn ""
11508   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11509         (compare:CC
11510          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11511                                        [(match_operand 2 "cc_reg_operand" "y,y")
11512                                         (const_int 0)])
11513                     (match_operand:SI 3 "const_int_operand" "n,n"))
11514          (const_int 0)))
11515    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11516         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11517                    (match_dup 3)))]
11518   ""
11519   "*
11521   int is_bit = ccr_bit (operands[1], 1);
11522   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11523   int count;
11525   /* Force split for non-cc0 compare.  */
11526   if (which_alternative == 1)
11527      return \"#\";
11529   if (is_bit >= put_bit)
11530     count = is_bit - put_bit;
11531   else
11532     count = 32 - (put_bit - is_bit);
11534   operands[5] = GEN_INT (count);
11535   operands[6] = GEN_INT (put_bit);
11537   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11539   [(set_attr "type" "shift")
11540    (set_attr "dot" "yes")
11541    (set_attr "length" "8,16")])
11543 (define_split
11544   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11545         (compare:CC
11546          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11547                                        [(match_operand 2 "cc_reg_operand" "")
11548                                         (const_int 0)])
11549                     (match_operand:SI 3 "const_int_operand" ""))
11550          (const_int 0)))
11551    (set (match_operand:SI 4 "gpc_reg_operand" "")
11552         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11553                    (match_dup 3)))]
11554   "reload_completed"
11555   [(set (match_dup 4)
11556         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11557                    (match_dup 3)))
11558    (set (match_dup 0)
11559         (compare:CC (match_dup 4)
11560                     (const_int 0)))]
11561   "")
11564 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11565                               (DI "rKJI")])
11567 (define_insn_and_split "eq<mode>3"
11568   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11569         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11570                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11571    (clobber (match_scratch:GPR 3 "=r"))
11572    (clobber (match_scratch:GPR 4 "=r"))]
11573   ""
11574   "#"
11575   ""
11576   [(set (match_dup 4)
11577         (clz:GPR (match_dup 3)))
11578    (set (match_dup 0)
11579         (lshiftrt:GPR (match_dup 4)
11580                       (match_dup 5)))]
11582   operands[3] = rs6000_emit_eqne (<MODE>mode,
11583                                   operands[1], operands[2], operands[3]);
11585   if (GET_CODE (operands[4]) == SCRATCH)
11586     operands[4] = gen_reg_rtx (<MODE>mode);
11588   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11590   [(set (attr "length")
11591         (if_then_else (match_test "operands[2] == const0_rtx")
11592                       (const_string "8")
11593                       (const_string "12")))])
11595 (define_insn_and_split "ne<mode>3"
11596   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11597         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11598               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11599    (clobber (match_scratch:P 3 "=r"))
11600    (clobber (match_scratch:P 4 "=r"))
11601    (clobber (reg:P CA_REGNO))]
11602   "!TARGET_ISEL"
11603   "#"
11604   ""
11605   [(parallel [(set (match_dup 4)
11606                    (plus:P (match_dup 3)
11607                            (const_int -1)))
11608               (set (reg:P CA_REGNO)
11609                    (ne:P (match_dup 3)
11610                          (const_int 0)))])
11611    (parallel [(set (match_dup 0)
11612                    (plus:P (plus:P (not:P (match_dup 4))
11613                                    (reg:P CA_REGNO))
11614                            (match_dup 3)))
11615               (clobber (reg:P CA_REGNO))])]
11617   operands[3] = rs6000_emit_eqne (<MODE>mode,
11618                                   operands[1], operands[2], operands[3]);
11620   if (GET_CODE (operands[4]) == SCRATCH)
11621     operands[4] = gen_reg_rtx (<MODE>mode);
11623   [(set (attr "length")
11624         (if_then_else (match_test "operands[2] == const0_rtx")
11625                       (const_string "8")
11626                       (const_string "12")))])
11628 (define_insn_and_split "*neg_eq_<mode>"
11629   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11630         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11631                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11632    (clobber (match_scratch:P 3 "=r"))
11633    (clobber (match_scratch:P 4 "=r"))
11634    (clobber (reg:P CA_REGNO))]
11635   ""
11636   "#"
11637   ""
11638   [(parallel [(set (match_dup 4)
11639                    (plus:P (match_dup 3)
11640                            (const_int -1)))
11641               (set (reg:P CA_REGNO)
11642                    (ne:P (match_dup 3)
11643                          (const_int 0)))])
11644    (parallel [(set (match_dup 0)
11645                    (plus:P (reg:P CA_REGNO)
11646                            (const_int -1)))
11647               (clobber (reg:P CA_REGNO))])]
11649   operands[3] = rs6000_emit_eqne (<MODE>mode,
11650                                   operands[1], operands[2], operands[3]);
11652   if (GET_CODE (operands[4]) == SCRATCH)
11653     operands[4] = gen_reg_rtx (<MODE>mode);
11655   [(set (attr "length")
11656         (if_then_else (match_test "operands[2] == const0_rtx")
11657                       (const_string "8")
11658                       (const_string "12")))])
11660 (define_insn_and_split "*neg_ne_<mode>"
11661   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11662         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11663                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11664    (clobber (match_scratch:P 3 "=r"))
11665    (clobber (match_scratch:P 4 "=r"))
11666    (clobber (reg:P CA_REGNO))]
11667   ""
11668   "#"
11669   ""
11670   [(parallel [(set (match_dup 4)
11671                    (neg:P (match_dup 3)))
11672               (set (reg:P CA_REGNO)
11673                    (eq:P (match_dup 3)
11674                          (const_int 0)))])
11675    (parallel [(set (match_dup 0)
11676                    (plus:P (reg:P CA_REGNO)
11677                            (const_int -1)))
11678               (clobber (reg:P CA_REGNO))])]
11680   operands[3] = rs6000_emit_eqne (<MODE>mode,
11681                                   operands[1], operands[2], operands[3]);
11683   if (GET_CODE (operands[4]) == SCRATCH)
11684     operands[4] = gen_reg_rtx (<MODE>mode);
11686   [(set (attr "length")
11687         (if_then_else (match_test "operands[2] == const0_rtx")
11688                       (const_string "8")
11689                       (const_string "12")))])
11691 (define_insn_and_split "*plus_eq_<mode>"
11692   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11693         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11694                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11695                 (match_operand:P 3 "gpc_reg_operand" "r")))
11696    (clobber (match_scratch:P 4 "=r"))
11697    (clobber (match_scratch:P 5 "=r"))
11698    (clobber (reg:P CA_REGNO))]
11699   ""
11700   "#"
11701   ""
11702   [(parallel [(set (match_dup 5)
11703                    (neg:P (match_dup 4)))
11704               (set (reg:P CA_REGNO)
11705                    (eq:P (match_dup 4)
11706                          (const_int 0)))])
11707    (parallel [(set (match_dup 0)
11708                    (plus:P (match_dup 3)
11709                            (reg:P CA_REGNO)))
11710               (clobber (reg:P CA_REGNO))])]
11712   operands[4] = rs6000_emit_eqne (<MODE>mode,
11713                                   operands[1], operands[2], operands[4]);
11715   if (GET_CODE (operands[5]) == SCRATCH)
11716     operands[5] = gen_reg_rtx (<MODE>mode);
11718   [(set (attr "length")
11719         (if_then_else (match_test "operands[2] == const0_rtx")
11720                       (const_string "8")
11721                       (const_string "12")))])
11723 (define_insn_and_split "*plus_ne_<mode>"
11724   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11725         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11726                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11727                 (match_operand:P 3 "gpc_reg_operand" "r")))
11728    (clobber (match_scratch:P 4 "=r"))
11729    (clobber (match_scratch:P 5 "=r"))
11730    (clobber (reg:P CA_REGNO))]
11731   ""
11732   "#"
11733   ""
11734   [(parallel [(set (match_dup 5)
11735                    (plus:P (match_dup 4)
11736                            (const_int -1)))
11737               (set (reg:P CA_REGNO)
11738                    (ne:P (match_dup 4)
11739                          (const_int 0)))])
11740    (parallel [(set (match_dup 0)
11741                    (plus:P (match_dup 3)
11742                            (reg:P CA_REGNO)))
11743               (clobber (reg:P CA_REGNO))])]
11745   operands[4] = rs6000_emit_eqne (<MODE>mode,
11746                                   operands[1], operands[2], operands[4]);
11748   if (GET_CODE (operands[5]) == SCRATCH)
11749     operands[5] = gen_reg_rtx (<MODE>mode);
11751   [(set (attr "length")
11752         (if_then_else (match_test "operands[2] == const0_rtx")
11753                       (const_string "8")
11754                       (const_string "12")))])
11756 (define_insn_and_split "*minus_eq_<mode>"
11757   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11758         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11759                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11760                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11761    (clobber (match_scratch:P 4 "=r"))
11762    (clobber (match_scratch:P 5 "=r"))
11763    (clobber (reg:P CA_REGNO))]
11764   ""
11765   "#"
11766   ""
11767   [(parallel [(set (match_dup 5)
11768                    (plus:P (match_dup 4)
11769                            (const_int -1)))
11770               (set (reg:P CA_REGNO)
11771                    (ne:P (match_dup 4)
11772                          (const_int 0)))])
11773    (parallel [(set (match_dup 0)
11774                    (plus:P (plus:P (match_dup 3)
11775                                    (reg:P CA_REGNO))
11776                            (const_int -1)))
11777               (clobber (reg:P CA_REGNO))])]
11779   operands[4] = rs6000_emit_eqne (<MODE>mode,
11780                                   operands[1], operands[2], operands[4]);
11782   if (GET_CODE (operands[5]) == SCRATCH)
11783     operands[5] = gen_reg_rtx (<MODE>mode);
11785   [(set (attr "length")
11786         (if_then_else (match_test "operands[2] == const0_rtx")
11787                       (const_string "8")
11788                       (const_string "12")))])
11790 (define_insn_and_split "*minus_ne_<mode>"
11791   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11792         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11793                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11794                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11795    (clobber (match_scratch:P 4 "=r"))
11796    (clobber (match_scratch:P 5 "=r"))
11797    (clobber (reg:P CA_REGNO))]
11798   ""
11799   "#"
11800   ""
11801   [(parallel [(set (match_dup 5)
11802                    (neg:P (match_dup 4)))
11803               (set (reg:P CA_REGNO)
11804                    (eq:P (match_dup 4)
11805                          (const_int 0)))])
11806    (parallel [(set (match_dup 0)
11807                    (plus:P (plus:P (match_dup 3)
11808                                    (reg:P CA_REGNO))
11809                            (const_int -1)))
11810               (clobber (reg:P CA_REGNO))])]
11812   operands[4] = rs6000_emit_eqne (<MODE>mode,
11813                                   operands[1], operands[2], operands[4]);
11815   if (GET_CODE (operands[5]) == SCRATCH)
11816     operands[5] = gen_reg_rtx (<MODE>mode);
11818   [(set (attr "length")
11819         (if_then_else (match_test "operands[2] == const0_rtx")
11820                       (const_string "8")
11821                       (const_string "12")))])
11823 (define_insn_and_split "*eqsi3_ext<mode>"
11824   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11825         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11826                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11827    (clobber (match_scratch:SI 3 "=r"))
11828    (clobber (match_scratch:SI 4 "=r"))]
11829   ""
11830   "#"
11831   ""
11832   [(set (match_dup 4)
11833         (clz:SI (match_dup 3)))
11834    (set (match_dup 0)
11835         (zero_extend:EXTSI
11836           (lshiftrt:SI (match_dup 4)
11837                        (const_int 5))))]
11839   operands[3] = rs6000_emit_eqne (SImode,
11840                                   operands[1], operands[2], operands[3]);
11842   if (GET_CODE (operands[4]) == SCRATCH)
11843     operands[4] = gen_reg_rtx (SImode);
11845   [(set (attr "length")
11846         (if_then_else (match_test "operands[2] == const0_rtx")
11847                       (const_string "8")
11848                       (const_string "12")))])
11850 (define_insn_and_split "*nesi3_ext<mode>"
11851   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11852         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11853                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11854    (clobber (match_scratch:SI 3 "=r"))
11855    (clobber (match_scratch:SI 4 "=r"))
11856    (clobber (match_scratch:EXTSI 5 "=r"))]
11857   ""
11858   "#"
11859   ""
11860   [(set (match_dup 4)
11861         (clz:SI (match_dup 3)))
11862    (set (match_dup 5)
11863         (zero_extend:EXTSI
11864           (lshiftrt:SI (match_dup 4)
11865                        (const_int 5))))
11866    (set (match_dup 0)
11867         (xor:EXTSI (match_dup 5)
11868                    (const_int 1)))]
11870   operands[3] = rs6000_emit_eqne (SImode,
11871                                   operands[1], operands[2], operands[3]);
11873   if (GET_CODE (operands[4]) == SCRATCH)
11874     operands[4] = gen_reg_rtx (SImode);
11875   if (GET_CODE (operands[5]) == SCRATCH)
11876     operands[5] = gen_reg_rtx (<MODE>mode);
11878   [(set (attr "length")
11879         (if_then_else (match_test "operands[2] == const0_rtx")
11880                       (const_string "12")
11881                       (const_string "16")))])
11883 ;; Define both directions of branch and return.  If we need a reload
11884 ;; register, we'd rather use CR0 since it is much easier to copy a
11885 ;; register CC value to there.
11887 (define_insn ""
11888   [(set (pc)
11889         (if_then_else (match_operator 1 "branch_comparison_operator"
11890                                       [(match_operand 2
11891                                                       "cc_reg_operand" "y")
11892                                        (const_int 0)])
11893                       (label_ref (match_operand 0 "" ""))
11894                       (pc)))]
11895   ""
11896   "*
11898   return output_cbranch (operands[1], \"%l0\", 0, insn);
11900   [(set_attr "type" "branch")])
11902 (define_insn ""
11903   [(set (pc)
11904         (if_then_else (match_operator 0 "branch_comparison_operator"
11905                                       [(match_operand 1
11906                                                       "cc_reg_operand" "y")
11907                                        (const_int 0)])
11908                       (any_return)
11909                       (pc)))]
11910   "<return_pred>"
11911   "*
11913   return output_cbranch (operands[0], NULL, 0, insn);
11915   [(set_attr "type" "jmpreg")
11916    (set_attr "length" "4")])
11918 (define_insn ""
11919   [(set (pc)
11920         (if_then_else (match_operator 1 "branch_comparison_operator"
11921                                       [(match_operand 2
11922                                                       "cc_reg_operand" "y")
11923                                        (const_int 0)])
11924                       (pc)
11925                       (label_ref (match_operand 0 "" ""))))]
11926   ""
11927   "*
11929   return output_cbranch (operands[1], \"%l0\", 1, insn);
11931   [(set_attr "type" "branch")])
11933 (define_insn ""
11934   [(set (pc)
11935         (if_then_else (match_operator 0 "branch_comparison_operator"
11936                                       [(match_operand 1
11937                                                       "cc_reg_operand" "y")
11938                                        (const_int 0)])
11939                       (pc)
11940                       (any_return)))]
11941   "<return_pred>"
11942   "*
11944   return output_cbranch (operands[0], NULL, 1, insn);
11946   [(set_attr "type" "jmpreg")
11947    (set_attr "length" "4")])
11949 ;; Logic on condition register values.
11951 ; This pattern matches things like
11952 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11953 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
11954 ;                                  (const_int 1)))
11955 ; which are generated by the branch logic.
11956 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11958 (define_insn "*cceq_ior_compare"
11959   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11960         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11961                         [(match_operator:SI 2
11962                                       "branch_positive_comparison_operator"
11963                                       [(match_operand 3
11964                                                       "cc_reg_operand" "y,y")
11965                                        (const_int 0)])
11966                          (match_operator:SI 4
11967                                       "branch_positive_comparison_operator"
11968                                       [(match_operand 5
11969                                                       "cc_reg_operand" "0,y")
11970                                        (const_int 0)])])
11971                       (const_int 1)))]
11972   ""
11973   "cr%q1 %E0,%j2,%j4"
11974   [(set_attr "type" "cr_logical,delayed_cr")])
11976 ; Why is the constant -1 here, but 1 in the previous pattern?
11977 ; Because ~1 has all but the low bit set.
11978 (define_insn ""
11979   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11980         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11981                         [(not:SI (match_operator:SI 2
11982                                       "branch_positive_comparison_operator"
11983                                       [(match_operand 3
11984                                                       "cc_reg_operand" "y,y")
11985                                        (const_int 0)]))
11986                          (match_operator:SI 4
11987                                 "branch_positive_comparison_operator"
11988                                 [(match_operand 5
11989                                                 "cc_reg_operand" "0,y")
11990                                  (const_int 0)])])
11991                       (const_int -1)))]
11992   ""
11993   "cr%q1 %E0,%j2,%j4"
11994   [(set_attr "type" "cr_logical,delayed_cr")])
11996 (define_insn "*cceq_rev_compare"
11997   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11998         (compare:CCEQ (match_operator:SI 1
11999                                       "branch_positive_comparison_operator"
12000                                       [(match_operand 2
12001                                                       "cc_reg_operand" "0,y")
12002                                        (const_int 0)])
12003                       (const_int 0)))]
12004   ""
12005   "crnot %E0,%j1"
12006   [(set_attr "type" "cr_logical,delayed_cr")])
12008 ;; If we are comparing the result of two comparisons, this can be done
12009 ;; using creqv or crxor.
12011 (define_insn_and_split ""
12012   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12013         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12014                               [(match_operand 2 "cc_reg_operand" "y")
12015                                (const_int 0)])
12016                       (match_operator 3 "branch_comparison_operator"
12017                               [(match_operand 4 "cc_reg_operand" "y")
12018                                (const_int 0)])))]
12019   ""
12020   "#"
12021   ""
12022   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12023                                     (match_dup 5)))]
12024   "
12026   int positive_1, positive_2;
12028   positive_1 = branch_positive_comparison_operator (operands[1],
12029                                                     GET_MODE (operands[1]));
12030   positive_2 = branch_positive_comparison_operator (operands[3],
12031                                                     GET_MODE (operands[3]));
12033   if (! positive_1)
12034     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12035                                                             GET_CODE (operands[1])),
12036                                   SImode,
12037                                   operands[2], const0_rtx);
12038   else if (GET_MODE (operands[1]) != SImode)
12039     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12040                                   operands[2], const0_rtx);
12042   if (! positive_2)
12043     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12044                                                             GET_CODE (operands[3])),
12045                                   SImode,
12046                                   operands[4], const0_rtx);
12047   else if (GET_MODE (operands[3]) != SImode)
12048     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12049                                   operands[4], const0_rtx);
12051   if (positive_1 == positive_2)
12052     {
12053       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12054       operands[5] = constm1_rtx;
12055     }
12056   else
12057     {
12058       operands[5] = const1_rtx;
12059     }
12062 ;; Unconditional branch and return.
12064 (define_insn "jump"
12065   [(set (pc)
12066         (label_ref (match_operand 0 "" "")))]
12067   ""
12068   "b %l0"
12069   [(set_attr "type" "branch")])
12071 (define_insn "<return_str>return"
12072   [(any_return)]
12073   "<return_pred>"
12074   "blr"
12075   [(set_attr "type" "jmpreg")])
12077 (define_expand "indirect_jump"
12078   [(set (pc) (match_operand 0 "register_operand" ""))])
12080 (define_insn "*indirect_jump<mode>"
12081   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12082   ""
12083   "@
12084    bctr
12085    blr"
12086   [(set_attr "type" "jmpreg")])
12088 ;; Table jump for switch statements:
12089 (define_expand "tablejump"
12090   [(use (match_operand 0 "" ""))
12091    (use (label_ref (match_operand 1 "" "")))]
12092   ""
12093   "
12095   if (TARGET_32BIT)
12096     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12097   else
12098     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12099   DONE;
12102 (define_expand "tablejumpsi"
12103   [(set (match_dup 3)
12104         (plus:SI (match_operand:SI 0 "" "")
12105                  (match_dup 2)))
12106    (parallel [(set (pc) (match_dup 3))
12107               (use (label_ref (match_operand 1 "" "")))])]
12108   "TARGET_32BIT"
12109   "
12110 { operands[0] = force_reg (SImode, operands[0]);
12111   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12112   operands[3] = gen_reg_rtx (SImode);
12115 (define_expand "tablejumpdi"
12116   [(set (match_dup 4)
12117         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12118    (set (match_dup 3)
12119         (plus:DI (match_dup 4)
12120                  (match_dup 2)))
12121    (parallel [(set (pc) (match_dup 3))
12122               (use (label_ref (match_operand 1 "" "")))])]
12123   "TARGET_64BIT"
12124   "
12125 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12126   operands[3] = gen_reg_rtx (DImode);
12127   operands[4] = gen_reg_rtx (DImode);
12130 (define_insn "*tablejump<mode>_internal1"
12131   [(set (pc)
12132         (match_operand:P 0 "register_operand" "c,*l"))
12133    (use (label_ref (match_operand 1 "" "")))]
12134   ""
12135   "@
12136    bctr
12137    blr"
12138   [(set_attr "type" "jmpreg")])
12140 (define_insn "nop"
12141   [(unspec [(const_int 0)] UNSPEC_NOP)]
12142   ""
12143   "nop")
12145 (define_insn "group_ending_nop"
12146   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12147   ""
12148   "*
12150   if (rs6000_cpu_attr == CPU_POWER6)
12151     return \"ori 1,1,0\";
12152   return \"ori 2,2,0\";
12155 ;; Define the subtract-one-and-jump insns, starting with the template
12156 ;; so loop.c knows what to generate.
12158 (define_expand "doloop_end"
12159   [(use (match_operand 0 "" ""))        ; loop pseudo
12160    (use (match_operand 1 "" ""))]       ; label
12161   ""
12162   "
12164   if (TARGET_64BIT)
12165     {
12166       if (GET_MODE (operands[0]) != DImode)
12167         FAIL;
12168       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12169     }
12170   else
12171     {
12172       if (GET_MODE (operands[0]) != SImode)
12173         FAIL;
12174       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12175     }
12176   DONE;
12179 (define_expand "ctr<mode>"
12180   [(parallel [(set (pc)
12181                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12182                                      (const_int 1))
12183                                  (label_ref (match_operand 1 "" ""))
12184                                  (pc)))
12185               (set (match_dup 0)
12186                    (plus:P (match_dup 0)
12187                             (const_int -1)))
12188               (clobber (match_scratch:CC 2 ""))
12189               (clobber (match_scratch:P 3 ""))])]
12190   ""
12191   "")
12193 ;; We need to be able to do this for any operand, including MEM, or we
12194 ;; will cause reload to blow up since we don't allow output reloads on
12195 ;; JUMP_INSNs.
12196 ;; For the length attribute to be calculated correctly, the
12197 ;; label MUST be operand 0.
12199 (define_insn "*ctr<mode>_internal1"
12200   [(set (pc)
12201         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12202                           (const_int 1))
12203                       (label_ref (match_operand 0 "" ""))
12204                       (pc)))
12205    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12206         (plus:P (match_dup 1)
12207                  (const_int -1)))
12208    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12209    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12210   ""
12211   "*
12213   if (which_alternative != 0)
12214     return \"#\";
12215   else if (get_attr_length (insn) == 4)
12216     return \"bdnz %l0\";
12217   else
12218     return \"bdz $+8\;b %l0\";
12220   [(set_attr "type" "branch")
12221    (set_attr "length" "*,16,20,20")])
12223 (define_insn "*ctr<mode>_internal2"
12224   [(set (pc)
12225         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12226                           (const_int 1))
12227                       (pc)
12228                       (label_ref (match_operand 0 "" ""))))
12229    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12230         (plus:P (match_dup 1)
12231                  (const_int -1)))
12232    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12233    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12234   ""
12235   "*
12237   if (which_alternative != 0)
12238     return \"#\";
12239   else if (get_attr_length (insn) == 4)
12240     return \"bdz %l0\";
12241   else
12242     return \"bdnz $+8\;b %l0\";
12244   [(set_attr "type" "branch")
12245    (set_attr "length" "*,16,20,20")])
12247 ;; Similar but use EQ
12249 (define_insn "*ctr<mode>_internal5"
12250   [(set (pc)
12251         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12252                           (const_int 1))
12253                       (label_ref (match_operand 0 "" ""))
12254                       (pc)))
12255    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12256         (plus:P (match_dup 1)
12257                  (const_int -1)))
12258    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12259    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12260   ""
12261   "*
12263   if (which_alternative != 0)
12264     return \"#\";
12265   else if (get_attr_length (insn) == 4)
12266     return \"bdz %l0\";
12267   else
12268     return \"bdnz $+8\;b %l0\";
12270   [(set_attr "type" "branch")
12271    (set_attr "length" "*,16,20,20")])
12273 (define_insn "*ctr<mode>_internal6"
12274   [(set (pc)
12275         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12276                           (const_int 1))
12277                       (pc)
12278                       (label_ref (match_operand 0 "" ""))))
12279    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12280         (plus:P (match_dup 1)
12281                  (const_int -1)))
12282    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12283    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12284   ""
12285   "*
12287   if (which_alternative != 0)
12288     return \"#\";
12289   else if (get_attr_length (insn) == 4)
12290     return \"bdnz %l0\";
12291   else
12292     return \"bdz $+8\;b %l0\";
12294   [(set_attr "type" "branch")
12295    (set_attr "length" "*,16,20,20")])
12297 ;; Now the splitters if we could not allocate the CTR register
12299 (define_split
12300   [(set (pc)
12301         (if_then_else (match_operator 2 "comparison_operator"
12302                                       [(match_operand:P 1 "gpc_reg_operand" "")
12303                                        (const_int 1)])
12304                       (match_operand 5 "" "")
12305                       (match_operand 6 "" "")))
12306    (set (match_operand:P 0 "int_reg_operand" "")
12307         (plus:P (match_dup 1) (const_int -1)))
12308    (clobber (match_scratch:CC 3 ""))
12309    (clobber (match_scratch:P 4 ""))]
12310   "reload_completed"
12311   [(set (match_dup 3)
12312         (compare:CC (match_dup 1)
12313                     (const_int 1)))
12314    (set (match_dup 0)
12315         (plus:P (match_dup 1)
12316                 (const_int -1)))
12317    (set (pc) (if_then_else (match_dup 7)
12318                            (match_dup 5)
12319                            (match_dup 6)))]
12320   "
12321 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12322                                 operands[3], const0_rtx); }")
12324 (define_split
12325   [(set (pc)
12326         (if_then_else (match_operator 2 "comparison_operator"
12327                                       [(match_operand:P 1 "gpc_reg_operand" "")
12328                                        (const_int 1)])
12329                       (match_operand 5 "" "")
12330                       (match_operand 6 "" "")))
12331    (set (match_operand:P 0 "nonimmediate_operand" "")
12332         (plus:P (match_dup 1) (const_int -1)))
12333    (clobber (match_scratch:CC 3 ""))
12334    (clobber (match_scratch:P 4 ""))]
12335   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12336   [(set (match_dup 3)
12337         (compare:CC (match_dup 1)
12338                     (const_int 1)))
12339    (set (match_dup 4)
12340         (plus:P (match_dup 1)
12341                 (const_int -1)))
12342    (set (match_dup 0)
12343         (match_dup 4))
12344    (set (pc) (if_then_else (match_dup 7)
12345                            (match_dup 5)
12346                            (match_dup 6)))]
12347   "
12348 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12349                                 operands[3], const0_rtx); }")
12351 (define_insn "trap"
12352   [(trap_if (const_int 1) (const_int 0))]
12353   ""
12354   "trap"
12355   [(set_attr "type" "trap")])
12357 (define_expand "ctrap<mode>4"
12358   [(trap_if (match_operator 0 "ordered_comparison_operator"
12359                             [(match_operand:GPR 1 "register_operand")
12360                              (match_operand:GPR 2 "reg_or_short_operand")])
12361             (match_operand 3 "zero_constant" ""))]
12362   ""
12363   "")
12365 (define_insn ""
12366   [(trap_if (match_operator 0 "ordered_comparison_operator"
12367                             [(match_operand:GPR 1 "register_operand" "r")
12368                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12369             (const_int 0))]
12370   ""
12371   "t<wd>%V0%I2 %1,%2"
12372   [(set_attr "type" "trap")])
12374 ;; Insns related to generating the function prologue and epilogue.
12376 (define_expand "prologue"
12377   [(use (const_int 0))]
12378   ""
12380   rs6000_emit_prologue ();
12381   if (!TARGET_SCHED_PROLOG)
12382     emit_insn (gen_blockage ());
12383   DONE;
12386 (define_insn "*movesi_from_cr_one"
12387   [(match_parallel 0 "mfcr_operation"
12388                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12389                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12390                                      (match_operand 3 "immediate_operand" "n")]
12391                           UNSPEC_MOVESI_FROM_CR))])]
12392   "TARGET_MFCRF"
12393   "*
12395   int mask = 0;
12396   int i;
12397   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12398   {
12399     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12400     operands[4] = GEN_INT (mask);
12401     output_asm_insn (\"mfcr %1,%4\", operands);
12402   }
12403   return \"\";
12405   [(set_attr "type" "mfcrf")])
12407 (define_insn "movesi_from_cr"
12408   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12409         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12410                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12411                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12412                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12413                    UNSPEC_MOVESI_FROM_CR))]
12414   ""
12415   "mfcr %0"
12416   [(set_attr "type" "mfcr")])
12418 (define_insn "*crsave"
12419   [(match_parallel 0 "crsave_operation"
12420                    [(set (match_operand:SI 1 "memory_operand" "=m")
12421                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12422   ""
12423   "stw %2,%1"
12424   [(set_attr "type" "store")])
12426 (define_insn "*stmw"
12427   [(match_parallel 0 "stmw_operation"
12428                    [(set (match_operand:SI 1 "memory_operand" "=m")
12429                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12430   "TARGET_MULTIPLE"
12431   "stmw %2,%1"
12432   [(set_attr "type" "store")
12433    (set_attr "update" "yes")
12434    (set_attr "indexed" "yes")])
12436 ; The following comment applies to:
12437 ;     save_gpregs_*
12438 ;     save_fpregs_*
12439 ;     restore_gpregs*
12440 ;     return_and_restore_gpregs*
12441 ;     return_and_restore_fpregs*
12442 ;     return_and_restore_fpregs_aix*
12444 ; The out-of-line save / restore functions expects one input argument.
12445 ; Since those are not standard call_insn's, we must avoid using
12446 ; MATCH_OPERAND for that argument. That way the register rename
12447 ; optimization will not try to rename this register.
12448 ; Each pattern is repeated for each possible register number used in 
12449 ; various ABIs (r11, r1, and for some functions r12)
12451 (define_insn "*save_gpregs_<mode>_r11"
12452   [(match_parallel 0 "any_parallel_operand"
12453                    [(clobber (reg:P 65))
12454                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12455                     (use (reg:P 11))
12456                     (set (match_operand:P 2 "memory_operand" "=m")
12457                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12458   ""
12459   "bl %1"
12460   [(set_attr "type" "branch")
12461    (set_attr "length" "4")])
12463 (define_insn "*save_gpregs_<mode>_r12"
12464   [(match_parallel 0 "any_parallel_operand"
12465                    [(clobber (reg:P 65))
12466                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12467                     (use (reg:P 12))
12468                     (set (match_operand:P 2 "memory_operand" "=m")
12469                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12470   ""
12471   "bl %1"
12472   [(set_attr "type" "branch")
12473    (set_attr "length" "4")])
12475 (define_insn "*save_gpregs_<mode>_r1"
12476   [(match_parallel 0 "any_parallel_operand"
12477                    [(clobber (reg:P 65))
12478                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12479                     (use (reg:P 1))
12480                     (set (match_operand:P 2 "memory_operand" "=m")
12481                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12482   ""
12483   "bl %1"
12484   [(set_attr "type" "branch")
12485    (set_attr "length" "4")])
12487 (define_insn "*save_fpregs_<mode>_r11"
12488   [(match_parallel 0 "any_parallel_operand"
12489                    [(clobber (reg:P 65))
12490                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12491                     (use (reg:P 11))
12492                     (set (match_operand:DF 2 "memory_operand" "=m")
12493                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12494   ""
12495   "bl %1"
12496   [(set_attr "type" "branch")
12497    (set_attr "length" "4")])
12499 (define_insn "*save_fpregs_<mode>_r12"
12500   [(match_parallel 0 "any_parallel_operand"
12501                    [(clobber (reg:P 65))
12502                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12503                     (use (reg:P 12))
12504                     (set (match_operand:DF 2 "memory_operand" "=m")
12505                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12506   ""
12507   "bl %1"
12508   [(set_attr "type" "branch")
12509    (set_attr "length" "4")])
12511 (define_insn "*save_fpregs_<mode>_r1"
12512   [(match_parallel 0 "any_parallel_operand"
12513                    [(clobber (reg:P 65))
12514                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12515                     (use (reg:P 1))
12516                     (set (match_operand:DF 2 "memory_operand" "=m")
12517                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12518   ""
12519   "bl %1"
12520   [(set_attr "type" "branch")
12521    (set_attr "length" "4")])
12523 ; This is to explain that changes to the stack pointer should
12524 ; not be moved over loads from or stores to stack memory.
12525 (define_insn "stack_tie"
12526   [(match_parallel 0 "tie_operand"
12527                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12528   ""
12529   ""
12530   [(set_attr "length" "0")])
12532 (define_expand "epilogue"
12533   [(use (const_int 0))]
12534   ""
12536   if (!TARGET_SCHED_PROLOG)
12537     emit_insn (gen_blockage ());
12538   rs6000_emit_epilogue (FALSE);
12539   DONE;
12542 ; On some processors, doing the mtcrf one CC register at a time is
12543 ; faster (like on the 604e).  On others, doing them all at once is
12544 ; faster; for instance, on the 601 and 750.
12546 (define_expand "movsi_to_cr_one"
12547   [(set (match_operand:CC 0 "cc_reg_operand" "")
12548         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12549                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12550   ""
12551   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12553 (define_insn "*movsi_to_cr"
12554   [(match_parallel 0 "mtcrf_operation"
12555                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12556                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12557                                      (match_operand 3 "immediate_operand" "n")]
12558                                     UNSPEC_MOVESI_TO_CR))])]
12559  ""
12560  "*
12562   int mask = 0;
12563   int i;
12564   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12565     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12566   operands[4] = GEN_INT (mask);
12567   return \"mtcrf %4,%2\";
12569   [(set_attr "type" "mtcr")])
12571 (define_insn "*mtcrfsi"
12572   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12573         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12574                     (match_operand 2 "immediate_operand" "n")]
12575                    UNSPEC_MOVESI_TO_CR))]
12576   "GET_CODE (operands[0]) == REG
12577    && CR_REGNO_P (REGNO (operands[0]))
12578    && GET_CODE (operands[2]) == CONST_INT
12579    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12580   "mtcrf %R0,%1"
12581   [(set_attr "type" "mtcr")])
12583 ; The load-multiple instructions have similar properties.
12584 ; Note that "load_multiple" is a name known to the machine-independent
12585 ; code that actually corresponds to the PowerPC load-string.
12587 (define_insn "*lmw"
12588   [(match_parallel 0 "lmw_operation"
12589                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12590                          (match_operand:SI 2 "memory_operand" "m"))])]
12591   "TARGET_MULTIPLE"
12592   "lmw %1,%2"
12593   [(set_attr "type" "load")
12594    (set_attr "update" "yes")
12595    (set_attr "indexed" "yes")
12596    (set_attr "cell_micro" "always")])
12598 (define_insn "*return_internal_<mode>"
12599   [(simple_return)
12600    (use (match_operand:P 0 "register_operand" "lc"))]
12601   ""
12602   "b%T0"
12603   [(set_attr "type" "jmpreg")])
12605 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12606 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12608 ; The following comment applies to:
12609 ;     save_gpregs_*
12610 ;     save_fpregs_*
12611 ;     restore_gpregs*
12612 ;     return_and_restore_gpregs*
12613 ;     return_and_restore_fpregs*
12614 ;     return_and_restore_fpregs_aix*
12616 ; The out-of-line save / restore functions expects one input argument.
12617 ; Since those are not standard call_insn's, we must avoid using
12618 ; MATCH_OPERAND for that argument. That way the register rename
12619 ; optimization will not try to rename this register.
12620 ; Each pattern is repeated for each possible register number used in 
12621 ; various ABIs (r11, r1, and for some functions r12)
12623 (define_insn "*restore_gpregs_<mode>_r11"
12624  [(match_parallel 0 "any_parallel_operand"
12625                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12626                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12627                    (use (reg:P 11))
12628                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12629                         (match_operand:P 4 "memory_operand" "m"))])]
12630  ""
12631  "bl %2"
12632  [(set_attr "type" "branch")
12633   (set_attr "length" "4")])
12635 (define_insn "*restore_gpregs_<mode>_r12"
12636  [(match_parallel 0 "any_parallel_operand"
12637                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12638                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12639                    (use (reg:P 12))
12640                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12641                         (match_operand:P 4 "memory_operand" "m"))])]
12642  ""
12643  "bl %2"
12644  [(set_attr "type" "branch")
12645   (set_attr "length" "4")])
12647 (define_insn "*restore_gpregs_<mode>_r1"
12648  [(match_parallel 0 "any_parallel_operand"
12649                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12650                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12651                    (use (reg:P 1))
12652                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12653                         (match_operand:P 4 "memory_operand" "m"))])]
12654  ""
12655  "bl %2"
12656  [(set_attr "type" "branch")
12657   (set_attr "length" "4")])
12659 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12660  [(match_parallel 0 "any_parallel_operand"
12661                   [(return)
12662                    (clobber (match_operand:P 1 "register_operand" "=l"))
12663                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12664                    (use (reg:P 11))
12665                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12666                         (match_operand:P 4 "memory_operand" "m"))])]
12667  ""
12668  "b %2"
12669  [(set_attr "type" "branch")
12670   (set_attr "length" "4")])
12672 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12673  [(match_parallel 0 "any_parallel_operand"
12674                   [(return)
12675                    (clobber (match_operand:P 1 "register_operand" "=l"))
12676                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12677                    (use (reg:P 12))
12678                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12679                         (match_operand:P 4 "memory_operand" "m"))])]
12680  ""
12681  "b %2"
12682  [(set_attr "type" "branch")
12683   (set_attr "length" "4")])
12685 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12686  [(match_parallel 0 "any_parallel_operand"
12687                   [(return)
12688                    (clobber (match_operand:P 1 "register_operand" "=l"))
12689                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12690                    (use (reg:P 1))
12691                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12692                         (match_operand:P 4 "memory_operand" "m"))])]
12693  ""
12694  "b %2"
12695  [(set_attr "type" "branch")
12696   (set_attr "length" "4")])
12698 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12699  [(match_parallel 0 "any_parallel_operand"
12700                   [(return)
12701                    (clobber (match_operand:P 1 "register_operand" "=l"))
12702                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12703                    (use (reg:P 11))
12704                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12705                         (match_operand:DF 4 "memory_operand" "m"))])]
12706  ""
12707  "b %2"
12708  [(set_attr "type" "branch")
12709   (set_attr "length" "4")])
12711 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12712  [(match_parallel 0 "any_parallel_operand"
12713                   [(return)
12714                    (clobber (match_operand:P 1 "register_operand" "=l"))
12715                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12716                    (use (reg:P 12))
12717                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12718                         (match_operand:DF 4 "memory_operand" "m"))])]
12719  ""
12720  "b %2"
12721  [(set_attr "type" "branch")
12722   (set_attr "length" "4")])
12724 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12725  [(match_parallel 0 "any_parallel_operand"
12726                   [(return)
12727                    (clobber (match_operand:P 1 "register_operand" "=l"))
12728                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12729                    (use (reg:P 1))
12730                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12731                         (match_operand:DF 4 "memory_operand" "m"))])]
12732  ""
12733  "b %2"
12734  [(set_attr "type" "branch")
12735   (set_attr "length" "4")])
12737 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12738  [(match_parallel 0 "any_parallel_operand"
12739                   [(return)
12740                    (use (match_operand:P 1 "register_operand" "l"))
12741                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12742                    (use (reg:P 11))
12743                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12744                         (match_operand:DF 4 "memory_operand" "m"))])]
12745  ""
12746  "b %2"
12747  [(set_attr "type" "branch")
12748   (set_attr "length" "4")])
12750 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12751  [(match_parallel 0 "any_parallel_operand"
12752                   [(return)
12753                    (use (match_operand:P 1 "register_operand" "l"))
12754                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12755                    (use (reg:P 1))
12756                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12757                         (match_operand:DF 4 "memory_operand" "m"))])]
12758  ""
12759  "b %2"
12760  [(set_attr "type" "branch")
12761   (set_attr "length" "4")])
12763 ; This is used in compiling the unwind routines.
12764 (define_expand "eh_return"
12765   [(use (match_operand 0 "general_operand" ""))]
12766   ""
12767   "
12769   if (TARGET_32BIT)
12770     emit_insn (gen_eh_set_lr_si (operands[0]));
12771   else
12772     emit_insn (gen_eh_set_lr_di (operands[0]));
12773   DONE;
12776 ; We can't expand this before we know where the link register is stored.
12777 (define_insn "eh_set_lr_<mode>"
12778   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12779                     UNSPECV_EH_RR)
12780    (clobber (match_scratch:P 1 "=&b"))]
12781   ""
12782   "#")
12784 (define_split
12785   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12786    (clobber (match_scratch 1 ""))]
12787   "reload_completed"
12788   [(const_int 0)]
12789   "
12791   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12792   DONE;
12795 (define_insn "prefetch"
12796   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12797              (match_operand:SI 1 "const_int_operand" "n")
12798              (match_operand:SI 2 "const_int_operand" "n"))]
12799   ""
12800   "*
12802   if (GET_CODE (operands[0]) == REG)
12803     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12804   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12806   [(set_attr "type" "load")])
12808 ;; Handle -fsplit-stack.
12810 (define_expand "split_stack_prologue"
12811   [(const_int 0)]
12812   ""
12814   rs6000_expand_split_stack_prologue ();
12815   DONE;
12818 (define_expand "load_split_stack_limit"
12819   [(set (match_operand 0)
12820         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12821   ""
12823   emit_insn (gen_rtx_SET (operands[0],
12824                           gen_rtx_UNSPEC (Pmode,
12825                                           gen_rtvec (1, const0_rtx),
12826                                           UNSPEC_STACK_CHECK)));
12827   DONE;
12830 (define_insn "load_split_stack_limit_di"
12831   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12832         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12833   "TARGET_64BIT"
12834   "ld %0,-0x7040(13)"
12835   [(set_attr "type" "load")
12836    (set_attr "update" "no")
12837    (set_attr "indexed" "no")])
12839 (define_insn "load_split_stack_limit_si"
12840   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12841         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12842   "!TARGET_64BIT"
12843   "lwz %0,-0x7020(2)"
12844   [(set_attr "type" "load")
12845    (set_attr "update" "no")
12846    (set_attr "indexed" "no")])
12848 ;; A return instruction which the middle-end doesn't see.
12849 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12850 ;; after the call to __morestack.
12851 (define_insn "split_stack_return"
12852   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12853   ""
12854   "blr"
12855   [(set_attr "type" "jmpreg")])
12857 ;; If there are operand 0 bytes available on the stack, jump to
12858 ;; operand 1.
12859 (define_expand "split_stack_space_check"
12860   [(set (match_dup 2)
12861         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12862    (set (match_dup 3)
12863         (minus (reg STACK_POINTER_REGNUM)
12864                (match_operand 0)))
12865    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12866    (set (pc) (if_then_else
12867               (geu (match_dup 4) (const_int 0))
12868               (label_ref (match_operand 1))
12869               (pc)))]
12870   ""
12872   rs6000_split_stack_space_check (operands[0], operands[1]);
12873   DONE;
12876 (define_insn "bpermd_<mode>"
12877   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12878         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12879                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12880   "TARGET_POPCNTD"
12881   "bpermd %0,%1,%2"
12882   [(set_attr "type" "popcnt")])
12885 ;; Builtin fma support.  Handle 
12886 ;; Note that the conditions for expansion are in the FMA_F iterator.
12888 (define_expand "fma<mode>4"
12889   [(set (match_operand:FMA_F 0 "register_operand" "")
12890         (fma:FMA_F
12891           (match_operand:FMA_F 1 "register_operand" "")
12892           (match_operand:FMA_F 2 "register_operand" "")
12893           (match_operand:FMA_F 3 "register_operand" "")))]
12894   ""
12895   "")
12897 (define_insn "*fma<mode>4_fpr"
12898   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12899         (fma:SFDF
12900           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12901           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12902           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12903   "TARGET_<MODE>_FPR"
12904   "@
12905    fmadd<Ftrad> %0,%1,%2,%3
12906    xsmadda<Fvsx> %x0,%x1,%x2
12907    xsmaddm<Fvsx> %x0,%x1,%x3"
12908   [(set_attr "type" "fp")
12909    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12911 ; Altivec only has fma and nfms.
12912 (define_expand "fms<mode>4"
12913   [(set (match_operand:FMA_F 0 "register_operand" "")
12914         (fma:FMA_F
12915           (match_operand:FMA_F 1 "register_operand" "")
12916           (match_operand:FMA_F 2 "register_operand" "")
12917           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12918   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12919   "")
12921 (define_insn "*fms<mode>4_fpr"
12922   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12923         (fma:SFDF
12924          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12925          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12926          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12927   "TARGET_<MODE>_FPR"
12928   "@
12929    fmsub<Ftrad> %0,%1,%2,%3
12930    xsmsuba<Fvsx> %x0,%x1,%x2
12931    xsmsubm<Fvsx> %x0,%x1,%x3"
12932   [(set_attr "type" "fp")
12933    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12935 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12936 (define_expand "fnma<mode>4"
12937   [(set (match_operand:FMA_F 0 "register_operand" "")
12938         (neg:FMA_F
12939           (fma:FMA_F
12940             (match_operand:FMA_F 1 "register_operand" "")
12941             (match_operand:FMA_F 2 "register_operand" "")
12942             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12943   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12944   "")
12946 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12947 (define_expand "fnms<mode>4"
12948   [(set (match_operand:FMA_F 0 "register_operand" "")
12949         (neg:FMA_F
12950           (fma:FMA_F
12951             (match_operand:FMA_F 1 "register_operand" "")
12952             (match_operand:FMA_F 2 "register_operand" "")
12953             (match_operand:FMA_F 3 "register_operand" ""))))]
12954   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12955   "")
12957 ; Not an official optab name, but used from builtins.
12958 (define_expand "nfma<mode>4"
12959   [(set (match_operand:FMA_F 0 "register_operand" "")
12960         (neg:FMA_F
12961           (fma:FMA_F
12962             (match_operand:FMA_F 1 "register_operand" "")
12963             (match_operand:FMA_F 2 "register_operand" "")
12964             (match_operand:FMA_F 3 "register_operand" ""))))]
12965   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12966   "")
12968 (define_insn "*nfma<mode>4_fpr"
12969   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12970         (neg:SFDF
12971          (fma:SFDF
12972           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12973           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12974           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12975   "TARGET_<MODE>_FPR"
12976   "@
12977    fnmadd<Ftrad> %0,%1,%2,%3
12978    xsnmadda<Fvsx> %x0,%x1,%x2
12979    xsnmaddm<Fvsx> %x0,%x1,%x3"
12980   [(set_attr "type" "fp")
12981    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12983 ; Not an official optab name, but used from builtins.
12984 (define_expand "nfms<mode>4"
12985   [(set (match_operand:FMA_F 0 "register_operand" "")
12986         (neg:FMA_F
12987           (fma:FMA_F
12988             (match_operand:FMA_F 1 "register_operand" "")
12989             (match_operand:FMA_F 2 "register_operand" "")
12990             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12991   ""
12992   "")
12994 (define_insn "*nfmssf4_fpr"
12995   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12996         (neg:SFDF
12997          (fma:SFDF
12998           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12999           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13000           (neg:SFDF
13001            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13002   "TARGET_<MODE>_FPR"
13003   "@
13004    fnmsub<Ftrad> %0,%1,%2,%3
13005    xsnmsuba<Fvsx> %x0,%x1,%x2
13006    xsnmsubm<Fvsx> %x0,%x1,%x3"
13007   [(set_attr "type" "fp")
13008    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13011 (define_expand "rs6000_get_timebase"
13012   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13013   ""
13015   if (TARGET_POWERPC64)
13016     emit_insn (gen_rs6000_mftb_di (operands[0]));
13017   else
13018     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13019   DONE;
13022 (define_insn "rs6000_get_timebase_ppc32"
13023   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13024         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13025    (clobber (match_scratch:SI 1 "=r"))
13026    (clobber (match_scratch:CC 2 "=y"))]
13027   "!TARGET_POWERPC64"
13029   if (WORDS_BIG_ENDIAN)
13030     if (TARGET_MFCRF)
13031       {
13032         return "mfspr %0,269\;"
13033                "mfspr %L0,268\;"
13034                "mfspr %1,269\;"
13035                "cmpw %2,%0,%1\;"
13036                "bne- %2,$-16";
13037       }
13038     else
13039       {
13040         return "mftbu %0\;"
13041                "mftb %L0\;"
13042                "mftbu %1\;"
13043                "cmpw %2,%0,%1\;"
13044                "bne- %2,$-16";
13045       }
13046   else
13047     if (TARGET_MFCRF)
13048       {
13049         return "mfspr %L0,269\;"
13050                "mfspr %0,268\;"
13051                "mfspr %1,269\;"
13052                "cmpw %2,%L0,%1\;"
13053                "bne- %2,$-16";
13054       }
13055     else
13056       {
13057         return "mftbu %L0\;"
13058                "mftb %0\;"
13059                "mftbu %1\;"
13060                "cmpw %2,%L0,%1\;"
13061                "bne- %2,$-16";
13062       }
13064   [(set_attr "length" "20")])
13066 (define_insn "rs6000_mftb_<mode>"
13067   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13068         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13069   ""
13071   if (TARGET_MFCRF)
13072     return "mfspr %0,268";
13073   else
13074     return "mftb %0";
13078 (define_insn "rs6000_mffs"
13079   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13080         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13081   "TARGET_HARD_FLOAT && TARGET_FPRS"
13082   "mffs %0")
13084 (define_insn "rs6000_mtfsf"
13085   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13086                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13087                     UNSPECV_MTFSF)]
13088   "TARGET_HARD_FLOAT && TARGET_FPRS"
13089   "mtfsf %0,%1")
13092 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13093 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13094 ;; register that is being loaded.  The fused ops must be physically adjacent.
13096 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13097 ;; before register allocation, and is meant to reduce the lifetime for the
13098 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13099 ;; to use the register that is being load.  The peephole2 then gathers any
13100 ;; other fused possibilities that it can find after register allocation.  If
13101 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13103 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13104 ;; before register allocation, so that we can avoid allocating a temporary base
13105 ;; register that won't be used, and that we try to load into base registers,
13106 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13107 ;; (addis followed by load) even on power8.
13109 (define_split
13110   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13111         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13112   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13113   [(parallel [(set (match_dup 0) (match_dup 2))
13114               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13115               (use (match_dup 3))
13116               (clobber (scratch:DI))])]
13118   operands[2] = fusion_wrap_memory_address (operands[1]);
13119   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13122 (define_insn "*toc_fusionload_<mode>"
13123   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13124         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13125    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13126    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13127    (clobber (match_scratch:DI 3 "=X,&b"))]
13128   "TARGET_TOC_FUSION_INT"
13130   if (base_reg_operand (operands[0], <MODE>mode))
13131     return emit_fusion_gpr_load (operands[0], operands[1]);
13133   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13135   [(set_attr "type" "load")
13136    (set_attr "length" "8")])
13138 (define_insn "*toc_fusionload_di"
13139   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13140         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13141    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13142    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13143    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13144   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13145    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13147   if (base_reg_operand (operands[0], DImode))
13148     return emit_fusion_gpr_load (operands[0], operands[1]);
13150   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13152   [(set_attr "type" "load")
13153    (set_attr "length" "8")])
13156 ;; Find cases where the addis that feeds into a load instruction is either used
13157 ;; once or is the same as the target register, and replace it with the fusion
13158 ;; insn
13160 (define_peephole2
13161   [(set (match_operand:P 0 "base_reg_operand" "")
13162         (match_operand:P 1 "fusion_gpr_addis" ""))
13163    (set (match_operand:INT1 2 "base_reg_operand" "")
13164         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13165   "TARGET_P8_FUSION
13166    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13167                          operands[3])"
13168   [(const_int 0)]
13170   expand_fusion_gpr_load (operands);
13171   DONE;
13174 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13175 ;; reload)
13177 (define_insn "fusion_gpr_load_<mode>"
13178   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13179         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13180                      UNSPEC_FUSION_GPR))]
13181   "TARGET_P8_FUSION"
13183   return emit_fusion_gpr_load (operands[0], operands[1]);
13185   [(set_attr "type" "load")
13186    (set_attr "length" "8")])
13189 ;; ISA 3.0 (power9) fusion support
13190 ;; Merge addis with floating load/store to FPRs (or GPRs).
13191 (define_peephole2
13192   [(set (match_operand:P 0 "base_reg_operand" "")
13193         (match_operand:P 1 "fusion_gpr_addis" ""))
13194    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13195         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13196   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13197    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13198   [(const_int 0)]
13200   expand_fusion_p9_load (operands);
13201   DONE;
13204 (define_peephole2
13205   [(set (match_operand:P 0 "base_reg_operand" "")
13206         (match_operand:P 1 "fusion_gpr_addis" ""))
13207    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13208         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13209   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13210    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13211   [(const_int 0)]
13213   expand_fusion_p9_store (operands);
13214   DONE;
13217 (define_peephole2
13218   [(set (match_operand:SDI 0 "int_reg_operand" "")
13219         (match_operand:SDI 1 "upper16_cint_operand" ""))
13220    (set (match_dup 0)
13221         (ior:SDI (match_dup 0)
13222                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13223   "TARGET_P9_FUSION"
13224   [(set (match_dup 0)
13225         (unspec:SDI [(match_dup 1)
13226                      (match_dup 2)] UNSPEC_FUSION_P9))])
13228 (define_peephole2
13229   [(set (match_operand:SDI 0 "int_reg_operand" "")
13230         (match_operand:SDI 1 "upper16_cint_operand" ""))
13231    (set (match_operand:SDI 2 "int_reg_operand" "")
13232         (ior:SDI (match_dup 0)
13233                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13234   "TARGET_P9_FUSION
13235    && !rtx_equal_p (operands[0], operands[2])
13236    && peep2_reg_dead_p (2, operands[0])"
13237   [(set (match_dup 2)
13238         (unspec:SDI [(match_dup 1)
13239                      (match_dup 3)] UNSPEC_FUSION_P9))])
13241 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13242 ;; reload).  Because we want to eventually have secondary_reload generate
13243 ;; these, they have to have a single alternative that gives the register
13244 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13245 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13246   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13247         (unspec:GPR_FUSION
13248          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13249          UNSPEC_FUSION_P9))
13250    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13251   "TARGET_P9_FUSION"
13253   /* This insn is a secondary reload insn, which cannot have alternatives.
13254      If we are not loading up register 0, use the power8 fusion instead.  */
13255   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13256     return emit_fusion_gpr_load (operands[0], operands[1]);
13258   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13260   [(set_attr "type" "load")
13261    (set_attr "length" "8")])
13263 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13264   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13265         (unspec:GPR_FUSION
13266          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13267          UNSPEC_FUSION_P9))
13268    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13269   "TARGET_P9_FUSION"
13271   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13273   [(set_attr "type" "store")
13274    (set_attr "length" "8")])
13276 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13277   [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13278         (unspec:FPR_FUSION
13279          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13280          UNSPEC_FUSION_P9))
13281    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13282   "TARGET_P9_FUSION"
13284   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13286   [(set_attr "type" "fpload")
13287    (set_attr "length" "8")])
13289 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13290   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13291         (unspec:FPR_FUSION
13292          [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13293          UNSPEC_FUSION_P9))
13294    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13295   "TARGET_P9_FUSION"
13297   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13299   [(set_attr "type" "fpstore")
13300    (set_attr "length" "8")])
13302 (define_insn "*fusion_p9_<mode>_constant"
13303   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13304         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13305                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13306                     UNSPEC_FUSION_P9))] 
13307   "TARGET_P9_FUSION"
13309   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13310   return "ori %0,%0,%2";
13312   [(set_attr "type" "two")
13313    (set_attr "length" "8")])
13316 ;; Miscellaneous ISA 2.06 (power7) instructions
13317 (define_insn "addg6s"
13318   [(set (match_operand:SI 0 "register_operand" "=r")
13319         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13320                     (match_operand:SI 2 "register_operand" "r")]
13321                    UNSPEC_ADDG6S))]
13322   "TARGET_POPCNTD"
13323   "addg6s %0,%1,%2"
13324   [(set_attr "type" "integer")
13325    (set_attr "length" "4")])
13327 (define_insn "cdtbcd"
13328   [(set (match_operand:SI 0 "register_operand" "=r")
13329         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13330                    UNSPEC_CDTBCD))]
13331   "TARGET_POPCNTD"
13332   "cdtbcd %0,%1"
13333   [(set_attr "type" "integer")
13334    (set_attr "length" "4")])
13336 (define_insn "cbcdtd"
13337   [(set (match_operand:SI 0 "register_operand" "=r")
13338         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13339                    UNSPEC_CBCDTD))]
13340   "TARGET_POPCNTD"
13341   "cbcdtd %0,%1"
13342   [(set_attr "type" "integer")
13343    (set_attr "length" "4")])
13345 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13346                                         UNSPEC_DIVEO
13347                                         UNSPEC_DIVEU
13348                                         UNSPEC_DIVEUO])
13350 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13351                              (UNSPEC_DIVEO      "eo")
13352                              (UNSPEC_DIVEU      "eu")
13353                              (UNSPEC_DIVEUO     "euo")])
13355 (define_insn "div<div_extend>_<mode>"
13356   [(set (match_operand:GPR 0 "register_operand" "=r")
13357         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13358                      (match_operand:GPR 2 "register_operand" "r")]
13359                     UNSPEC_DIV_EXTEND))]
13360   "TARGET_POPCNTD"
13361   "div<wd><div_extend> %0,%1,%2"
13362   [(set_attr "type" "div")
13363    (set_attr "size" "<bits>")])
13366 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13368 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13369 (define_mode_attr FP128_64 [(TF "DF")
13370                             (IF "DF")
13371                             (TD "DI")
13372                             (KF "DI")])
13374 (define_expand "unpack<mode>"
13375   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13376         (unspec:<FP128_64>
13377          [(match_operand:FMOVE128 1 "register_operand" "")
13378           (match_operand:QI 2 "const_0_to_1_operand" "")]
13379          UNSPEC_UNPACK_128BIT))]
13380   "FLOAT128_2REG_P (<MODE>mode)"
13381   "")
13383 (define_insn_and_split "unpack<mode>_dm"
13384   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13385         (unspec:<FP128_64>
13386          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13387           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13388          UNSPEC_UNPACK_128BIT))]
13389   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13390   "#"
13391   "&& reload_completed"
13392   [(set (match_dup 0) (match_dup 3))]
13394   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13396   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13397     {
13398       emit_note (NOTE_INSN_DELETED);
13399       DONE;
13400     }
13402   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13404   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13405    (set_attr "length" "4")])
13407 (define_insn_and_split "unpack<mode>_nodm"
13408   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13409         (unspec:<FP128_64>
13410          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13411           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13412          UNSPEC_UNPACK_128BIT))]
13413   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13414   "#"
13415   "&& reload_completed"
13416   [(set (match_dup 0) (match_dup 3))]
13418   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13420   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13421     {
13422       emit_note (NOTE_INSN_DELETED);
13423       DONE;
13424     }
13426   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13428   [(set_attr "type" "fp,fpstore")
13429    (set_attr "length" "4")])
13431 (define_insn_and_split "pack<mode>"
13432   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13433         (unspec:FMOVE128
13434          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13435           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13436          UNSPEC_PACK_128BIT))]
13437   "FLOAT128_2REG_P (<MODE>mode)"
13438   "@
13439    fmr %L0,%2
13440    #"
13441   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13442   [(set (match_dup 3) (match_dup 1))
13443    (set (match_dup 4) (match_dup 2))]
13445   unsigned dest_hi = REGNO (operands[0]);
13446   unsigned dest_lo = dest_hi + 1;
13448   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13449   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13451   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13452   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13454   [(set_attr "type" "fpsimple,fp")
13455    (set_attr "length" "4,8")])
13457 (define_insn "unpack<mode>"
13458   [(set (match_operand:DI 0 "register_operand" "=d,d")
13459         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13460                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13461          UNSPEC_UNPACK_128BIT))]
13462   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13464   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13465     return ASM_COMMENT_START " xxpermdi to same register";
13467   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13468   return "xxpermdi %x0,%x1,%x1,%3";
13470   [(set_attr "type" "vecperm")])
13472 (define_insn "pack<mode>"
13473   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13474         (unspec:FMOVE128_VSX
13475          [(match_operand:DI 1 "register_operand" "d")
13476           (match_operand:DI 2 "register_operand" "d")]
13477          UNSPEC_PACK_128BIT))]
13478   "TARGET_VSX"
13479   "xxpermdi %x0,%x1,%x2,0"
13480   [(set_attr "type" "vecperm")])
13484 ;; ISA 2.08 IEEE 128-bit floating point support.
13486 (define_insn "add<mode>3"
13487   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13488         (plus:IEEE128
13489          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13490          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13491   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13492   "xsaddqp %0,%1,%2"
13493   [(set_attr "type" "vecfloat")
13494    (set_attr "size" "128")])
13496 (define_insn "sub<mode>3"
13497   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13498         (minus:IEEE128
13499          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13500          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13501   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13502   "xssubqp %0,%1,%2"
13503   [(set_attr "type" "vecfloat")
13504    (set_attr "size" "128")])
13506 (define_insn "mul<mode>3"
13507   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13508         (mult:IEEE128
13509          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13510          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13511   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13512   "xsmulqp %0,%1,%2"
13513   [(set_attr "type" "vecfloat")
13514    (set_attr "size" "128")])
13516 (define_insn "div<mode>3"
13517   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13518         (div:IEEE128
13519          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13520          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13521   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13522   "xsdivqp %0,%1,%2"
13523   [(set_attr "type" "vecdiv")
13524    (set_attr "size" "128")])
13526 (define_insn "sqrt<mode>2"
13527   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13528         (sqrt:IEEE128
13529          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13530   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13531    "xssqrtqp %0,%1"
13532   [(set_attr "type" "vecdiv")
13533    (set_attr "size" "128")])
13535 (define_expand "copysign<mode>3"
13536   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13537    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13538    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13539   "FLOAT128_IEEE_P (<MODE>mode)"
13541   if (TARGET_FLOAT128_HW)
13542     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13543                                          operands[2]));
13544   else
13545     {
13546       rtx tmp = gen_reg_rtx (<MODE>mode);
13547       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13548                                            operands[2], tmp));
13549     }
13550   DONE;
13553 (define_insn "copysign<mode>3_hard"
13554   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13555         (unspec:IEEE128
13556          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13557           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13558          UNSPEC_COPYSIGN))]
13559   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13560    "xscpsgnqp %0,%2,%1"
13561   [(set_attr "type" "vecmove")
13562    (set_attr "size" "128")])
13564 (define_insn "copysign<mode>3_soft"
13565   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13566         (unspec:IEEE128
13567          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13568           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13569           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13570          UNSPEC_COPYSIGN))]
13571   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13572    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13573   [(set_attr "type" "veccomplex")
13574    (set_attr "length" "8")])
13576 (define_insn "neg<mode>2_hw"
13577   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13578         (neg:IEEE128
13579          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13580   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13581   "xsnegqp %0,%1"
13582   [(set_attr "type" "vecmove")
13583    (set_attr "size" "128")])
13586 (define_insn "abs<mode>2_hw"
13587   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13588         (abs:IEEE128
13589          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13590   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13591   "xsabsqp %0,%1"
13592   [(set_attr "type" "vecmove")
13593    (set_attr "size" "128")])
13596 (define_insn "*nabs<mode>2_hw"
13597   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13598         (neg:IEEE128
13599          (abs:IEEE128
13600           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13601   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13602   "xsnabsqp %0,%1"
13603   [(set_attr "type" "vecmove")
13604    (set_attr "size" "128")])
13606 ;; Initially don't worry about doing fusion
13607 (define_insn "*fma<mode>4_hw"
13608   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13609         (fma:IEEE128
13610          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13611          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13612          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13613   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13614   "xsmaddqp %0,%1,%2"
13615   [(set_attr "type" "vecfloat")
13616    (set_attr "size" "128")])
13618 (define_insn "*fms<mode>4_hw"
13619   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13620         (fma:IEEE128
13621          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13622          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13623          (neg:IEEE128
13624           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13625   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13626   "xsmsubqp %0,%1,%2"
13627   [(set_attr "type" "vecfloat")
13628    (set_attr "size" "128")])
13630 (define_insn "*nfma<mode>4_hw"
13631   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13632         (neg:IEEE128
13633          (fma:IEEE128
13634           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13635           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13636           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13637   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13638   "xsnmaddqp %0,%1,%2"
13639   [(set_attr "type" "vecfloat")
13640    (set_attr "size" "128")])
13642 (define_insn "*nfms<mode>4_hw"
13643   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13644         (neg:IEEE128
13645          (fma:IEEE128
13646           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13647           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13648           (neg:IEEE128
13649            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13650   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13651   "xsnmsubqp %0,%1,%2"
13652   [(set_attr "type" "vecfloat")
13653    (set_attr "size" "128")])
13655 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13656   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13657         (float_extend:IEEE128
13658          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13659   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13660   "xscvdpqp %0,%1"
13661   [(set_attr "type" "vecfloat")
13662    (set_attr "size" "128")])
13664 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13665 ;; point is a simple copy.
13666 (define_insn_and_split "extendkftf2"
13667   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13668         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13669   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13670   "@
13671    #
13672    xxlor %x0,%x1,%x1"
13673   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13674   [(const_int 0)]
13676   emit_note (NOTE_INSN_DELETED);
13677   DONE;
13679   [(set_attr "type" "*,veclogical")
13680    (set_attr "length" "0,4")])
13682 (define_insn_and_split "trunctfkf2"
13683   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13684         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13685   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13686   "@
13687    #
13688    xxlor %x0,%x1,%x1"
13689   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13690   [(const_int 0)]
13692   emit_note (NOTE_INSN_DELETED);
13693   DONE;
13695   [(set_attr "type" "*,veclogical")
13696    (set_attr "length" "0,4")])
13698 (define_insn "trunc<mode>df2_hw"
13699   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13700         (float_truncate:DF
13701          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13702   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13703   "xscvqpdp %0,%1"
13704   [(set_attr "type" "vecfloat")
13705    (set_attr "size" "128")])
13707 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13708 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13709 ;; conversion
13710 (define_insn_and_split "trunc<mode>sf2_hw"
13711   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13712         (float_truncate:SF
13713          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13714    (clobber (match_scratch:DF 2 "=v"))]
13715   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13716   "#"
13717   "&& 1"
13718   [(set (match_dup 2)
13719         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13720    (set (match_dup 0)
13721         (float_truncate:SF (match_dup 2)))]
13723   if (GET_CODE (operands[2]) == SCRATCH)
13724     operands[2] = gen_reg_rtx (DFmode);
13726   [(set_attr "type" "vecfloat")
13727    (set_attr "length" "8")])
13729 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13730 ;; allowed in the traditional floating point registers. Use V2DImode so that
13731 ;; we can get a value in an Altivec register.
13733 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13734   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13735         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13736    (clobber (match_scratch:V2DI 2 "=v,v"))]
13737   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13738   "#"
13739   "&& 1"
13740   [(pc)]
13742   convert_float128_to_int (operands, <CODE>);
13743   DONE;
13745   [(set_attr "length" "8")
13746    (set_attr "type" "mftgpr,fpstore")])
13748 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13749   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13750         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13751    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13752   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13753   "#"
13754   "&& 1"
13755   [(pc)]
13757   convert_float128_to_int (operands, <CODE>);
13758   DONE;
13760   [(set_attr "length" "8")
13761    (set_attr "type" "mftgpr,vecsimple,fpstore")])
13763 (define_insn_and_split "float<uns>_<mode>si2_hw"
13764   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13765         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13766    (clobber (match_scratch:V2DI 2 "=v,v"))]
13767   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13768   "#"
13769   "&& 1"
13770   [(pc)]
13772   convert_int_to_float128 (operands, <CODE>);
13773   DONE;
13775   [(set_attr "length" "8")
13776    (set_attr "type" "vecfloat")])
13778 (define_insn_and_split "float<uns>_<mode>di2_hw"
13779   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13780         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13781    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13782   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13783   "#"
13784   "&& 1"
13785   [(pc)]
13787   convert_int_to_float128 (operands, <CODE>);
13788   DONE;
13790   [(set_attr "length" "8")
13791    (set_attr "type" "vecfloat")])
13793 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13794 (define_insn "*xscvqp<su>wz_<mode>"
13795   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13796         (unspec:V2DI
13797          [(any_fix:SI
13798            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13799          UNSPEC_IEEE128_CONVERT))]
13800   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13801   "xscvqp<su>wz %0,%1"
13802   [(set_attr "type" "vecfloat")
13803    (set_attr "size" "128")])
13805 (define_insn "*xscvqp<su>dz_<mode>"
13806   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13807         (unspec:V2DI
13808          [(any_fix:DI
13809            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13810          UNSPEC_IEEE128_CONVERT))]
13811   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13812   "xscvqp<su>dz %0,%1"
13813   [(set_attr "type" "vecfloat")
13814    (set_attr "size" "128")])
13816 (define_insn "*xscv<su>dqp_<mode>"
13817   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13818         (any_float:IEEE128
13819          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13820                     UNSPEC_IEEE128_CONVERT)))]
13821   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13822   "xscv<su>dqp %0,%1"
13823   [(set_attr "type" "vecfloat")
13824    (set_attr "size" "128")])
13826 (define_insn "*ieee128_mfvsrd_64bit"
13827   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13828         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13829                    UNSPEC_IEEE128_MOVE))]
13830   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13831   "@
13832    mfvsrd %0,%x1
13833    stxsdx %x1,%y0
13834    xxlor %x0,%x1,%x1"
13835   [(set_attr "type" "mftgpr,fpstore,veclogical")])
13838 (define_insn "*ieee128_mfvsrd_32bit"
13839   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13840         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13841                    UNSPEC_IEEE128_MOVE))]
13842   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13843   "@
13844    stxsdx %x1,%y0
13845    xxlor %x0,%x1,%x1"
13846   [(set_attr "type" "fpstore,veclogical")])
13848 (define_insn "*ieee128_mfvsrwz"
13849   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13850         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13851                    UNSPEC_IEEE128_MOVE))]
13852   "TARGET_FLOAT128_HW"
13853   "@
13854    mfvsrwz %0,%x1
13855    stxsiwx %x1,%y0"
13856   [(set_attr "type" "mftgpr,fpstore")])
13858 ;; 0 says do sign-extension, 1 says zero-extension
13859 (define_insn "*ieee128_mtvsrw"
13860   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13861         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13862                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13863                      UNSPEC_IEEE128_MOVE))]
13864   "TARGET_FLOAT128_HW"
13865   "@
13866    mtvsrwa %x0,%1
13867    lxsiwax %x0,%y1
13868    mtvsrwz %x0,%1
13869    lxsiwzx %x0,%y1"
13870   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13873 (define_insn "*ieee128_mtvsrd_64bit"
13874   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13875         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13876                      UNSPEC_IEEE128_MOVE))]
13877   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13878   "@
13879    mtvsrd %x0,%1
13880    lxsdx %x0,%y1
13881    xxlor %x0,%x1,%x1"
13882   [(set_attr "type" "mffgpr,fpload,veclogical")])
13884 (define_insn "*ieee128_mtvsrd_32bit"
13885   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13886         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13887                      UNSPEC_IEEE128_MOVE))]
13888   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13889   "@
13890    lxsdx %x0,%y1
13891    xxlor %x0,%x1,%x1"
13892   [(set_attr "type" "fpload,veclogical")])
13894 ;; IEEE 128-bit instructions with round to odd semantics
13895 (define_insn "*trunc<mode>df2_odd"
13896   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13897         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13898                    UNSPEC_ROUND_TO_ODD))]
13899   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13900   "xscvqpdpo %0,%1"
13901   [(set_attr "type" "vecfloat")
13902    (set_attr "size" "128")])
13904 ;; IEEE 128-bit comparisons
13905 (define_insn "*cmp<mode>_hw"
13906   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13907         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13908                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13909   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13910    "xscmpuqp %0,%1,%2"
13911   [(set_attr "type" "veccmp")
13912    (set_attr "size" "128")])
13916 (include "sync.md")
13917 (include "vector.md")
13918 (include "vsx.md")
13919 (include "altivec.md")
13920 (include "spe.md")
13921 (include "dfp.md")
13922 (include "paired.md")
13923 (include "crypto.md")
13924 (include "htm.md")