re PR target/78594 (Bug in November 11th, 2016 change to rs6000.md)
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobf1ba8d4089be4629f86d7f61d79af763fb83e30e
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2016 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (SPE_ACC_REGNO               111)
54    (SPEFSCR_REGNO               112)
55    (FRAME_POINTER_REGNUM        113)
56    (TFHAR_REGNO                 114)
57    (TFIAR_REGNO                 115)
58    (TEXASR_REGNO                116)
59    (FIRST_SPE_HIGH_REGNO        117)
60    (LAST_SPE_HIGH_REGNO         148)
61   ])
64 ;; UNSPEC usage
67 (define_c_enum "unspec"
68   [UNSPEC_FRSP                  ; frsp for POWER machines
69    UNSPEC_PROBE_STACK           ; probe stack memory reference
70    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
71    UNSPEC_TOC                   ; address of the TOC (more-or-less)
72    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
73    UNSPEC_MOVSI_GOT
74    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
75    UNSPEC_FCTIWZ
76    UNSPEC_FRIM
77    UNSPEC_FRIN
78    UNSPEC_FRIP
79    UNSPEC_FRIZ
80    UNSPEC_XSRDPI
81    UNSPEC_LD_MPIC               ; load_macho_picbase
82    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
83    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
84    UNSPEC_TLSGD
85    UNSPEC_TLSLD
86    UNSPEC_MOVESI_FROM_CR
87    UNSPEC_MOVESI_TO_CR
88    UNSPEC_TLSDTPREL
89    UNSPEC_TLSDTPRELHA
90    UNSPEC_TLSDTPRELLO
91    UNSPEC_TLSGOTDTPREL
92    UNSPEC_TLSTPREL
93    UNSPEC_TLSTPRELHA
94    UNSPEC_TLSTPRELLO
95    UNSPEC_TLSGOTTPREL
96    UNSPEC_TLSTLS
97    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
98    UNSPEC_MV_CR_GT              ; move_from_CR_gt_bit
99    UNSPEC_STFIWX
100    UNSPEC_POPCNTB
101    UNSPEC_FRES
102    UNSPEC_SP_SET
103    UNSPEC_SP_TEST
104    UNSPEC_SYNC
105    UNSPEC_LWSYNC
106    UNSPEC_SYNC_OP
107    UNSPEC_ATOMIC
108    UNSPEC_CMPXCHG
109    UNSPEC_XCHG
110    UNSPEC_AND
111    UNSPEC_DLMZB
112    UNSPEC_DLMZB_CR
113    UNSPEC_DLMZB_STRLEN
114    UNSPEC_RSQRT
115    UNSPEC_TOCREL
116    UNSPEC_MACHOPIC_OFFSET
117    UNSPEC_BPERM
118    UNSPEC_COPYSIGN
119    UNSPEC_PARITY
120    UNSPEC_FCTIW
121    UNSPEC_FCTID
122    UNSPEC_LFIWAX
123    UNSPEC_LFIWZX
124    UNSPEC_FCTIWUZ
125    UNSPEC_NOP
126    UNSPEC_GRP_END_NOP
127    UNSPEC_P8V_FMRGOW
128    UNSPEC_P8V_MTVSRWZ
129    UNSPEC_P8V_RELOAD_FROM_GPR
130    UNSPEC_P8V_MTVSRD
131    UNSPEC_P8V_XXPERMDI
132    UNSPEC_P8V_RELOAD_FROM_VSX
133    UNSPEC_ADDG6S
134    UNSPEC_CDTBCD
135    UNSPEC_CBCDTD
136    UNSPEC_DIVE
137    UNSPEC_DIVEO
138    UNSPEC_DIVEU
139    UNSPEC_DIVEUO
140    UNSPEC_UNPACK_128BIT
141    UNSPEC_PACK_128BIT
142    UNSPEC_LSQ
143    UNSPEC_FUSION_GPR
144    UNSPEC_STACK_CHECK
145    UNSPEC_FUSION_P9
146    UNSPEC_FUSION_ADDIS
147    UNSPEC_ROUND_TO_ODD
148    UNSPEC_IEEE128_MOVE
149    UNSPEC_IEEE128_CONVERT
150    UNSPEC_SIGNBIT
151    UNSPEC_DOLOOP
152   ])
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
159   [UNSPECV_BLOCK
160    UNSPECV_LL                   ; load-locked
161    UNSPECV_SC                   ; store-conditional
162    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
163    UNSPECV_EH_RR                ; eh_reg_restore
164    UNSPECV_ISYNC                ; isync instruction
165    UNSPECV_MFTB                 ; move from time base
166    UNSPECV_NLGR                 ; non-local goto receiver
167    UNSPECV_MFFS                 ; Move from FPSCR
168    UNSPECV_MTFSF                ; Move to FPSCR Fields
169    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
170   ])
173 ;; Define an insn type attribute.  This is used in function unit delay
174 ;; computations.
175 (define_attr "type"
176   "integer,two,three,
177    add,logical,shift,insert,
178    mul,halfmul,div,
179    exts,cntlz,popcnt,isel,
180    load,store,fpload,fpstore,vecload,vecstore,
181    cmp,
182    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
185    brinc,
186    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188    veclogical,veccmpfx,vecexts,vecmove,
189    htm,htmsimple,dfp"
190   (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that.  If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210   (if_then_else (ior (match_operand 0 "indexed_address_mem")
211                      (match_operand 1 "indexed_address_mem"))
212                 (const_string "yes")
213                 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns.  See the comments for "indexed".
217 (define_attr "update" "no,yes"
218   (if_then_else (ior (match_operand 0 "update_address_mem")
219                      (match_operand 1 "update_address_mem"))
220                 (const_string "yes")
221                 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
224 ;; register?
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231   (if_then_else (and (eq_attr "type" "shift")
232                      (eq_attr "maybe_var_shift" "yes"))
233                 (if_then_else (match_operand 2 "gpc_reg_operand")
234                               (const_string "yes")
235                               (const_string "no"))
236                 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248   (if_then_else (eq_attr "type" "branch")
249                 (if_then_else (and (ge (minus (match_dup 0) (pc))
250                                        (const_int -32768))
251                                    (lt (minus (match_dup 0) (pc))
252                                        (const_int 32764)))
253                               (const_int 4)
254                               (const_int 8))
255                 (const_int 4)))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
259 (define_attr "cpu"
260   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261    ppc750,ppc7400,ppc7450,
262    ppc403,ppc405,ppc440,ppc476,
263    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264    power4,power5,power6,power7,power8,power9,
265    rs64a,mpccore,cell,ppca2,titan"
266   (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273                           (eq_attr "dot" "yes"))
274                      (and (eq_attr "type" "load")
275                           (eq_attr "sign_extend" "yes"))
276                      (and (eq_attr "type" "shift")
277                           (eq_attr "var_shift" "yes")))
278                 (const_string "always")
279                 (const_string "not")))
281 (automata_option "ndfa")
283 (include "rs64.md")
284 (include "mpc.md")
285 (include "40x.md")
286 (include "440.md")
287 (include "476.md")
288 (include "601.md")
289 (include "603.md")
290 (include "6xx.md")
291 (include "7xx.md")
292 (include "7450.md")
293 (include "8540.md")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
297 (include "e5500.md")
298 (include "e6500.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
305 (include "cell.md")
306 (include "xfpu.md")
307 (include "a2.md")
308 (include "titan.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
316 ;; Mode iterators
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Integer modes supported in VSX registers with ISA 3.0 instructions
329 (define_mode_iterator INT_ISA3 [QI HI SI DI])
331 ; Everything we can extend QImode to.
332 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend HImode to.
335 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend SImode to.
338 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
340 ; QImode or HImode for small integer moves and small atomic ops
341 (define_mode_iterator QHI [QI HI])
343 ; QImode, HImode, SImode for fused ops only for GPR loads
344 (define_mode_iterator QHSI [QI HI SI])
346 ; HImode or SImode for sign extended fusion ops
347 (define_mode_iterator HSI [HI SI])
349 ; SImode or DImode, even if DImode doesn't fit in GPRs.
350 (define_mode_iterator SDI [SI DI])
352 ; Types that can be fused with an ADDIS instruction to load or store a GPR
353 ; register that has reg+offset addressing.
354 (define_mode_iterator GPR_FUSION [QI
355                                   HI
356                                   SI
357                                   (DI   "TARGET_POWERPC64")
358                                   SF
359                                   (DF   "TARGET_POWERPC64")])
361 ; Types that can be fused with an ADDIS instruction to load or store a FPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator FPR_FUSION [DI SF DF])
365 ; The size of a pointer.  Also, the size of the value that a record-condition
366 ; (one with a '.') will compare; and the size used for arithmetic carries.
367 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
369 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
370 ; PTImode is GPR only)
371 (define_mode_iterator TI2 [TI PTI])
373 ; Any hardware-supported floating-point mode
374 (define_mode_iterator FP [
375   (SF "TARGET_HARD_FLOAT 
376    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
377   (DF "TARGET_HARD_FLOAT 
378    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
379   (TF "TARGET_HARD_FLOAT
380    && (TARGET_FPRS || TARGET_E500_DOUBLE)
381    && TARGET_LONG_DOUBLE_128")
382   (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
383   (KF "TARGET_FLOAT128_TYPE")
384   (DD "TARGET_DFP")
385   (TD "TARGET_DFP")])
387 ; Any fma capable floating-point mode.
388 (define_mode_iterator FMA_F [
389   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
390   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
391        || VECTOR_UNIT_VSX_P (DFmode)")
392   (V2SF "TARGET_PAIRED_FLOAT")
393   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
394   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
395   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
396   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
397   ])
399 ; Floating point move iterators to combine binary and decimal moves
400 (define_mode_iterator FMOVE32 [SF SD])
401 (define_mode_iterator FMOVE64 [DF DD])
402 (define_mode_iterator FMOVE64X [DI DF DD])
403 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
404                                 (IF "FLOAT128_IBM_P (IFmode)")
405                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
407 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
408                                     (IF "FLOAT128_2REG_P (IFmode)")
409                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
411 ; Iterators for 128 bit types for direct move
412 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
413                                     (V16QI "")
414                                     (V8HI  "")
415                                     (V4SI  "")
416                                     (V4SF  "")
417                                     (V2DI  "")
418                                     (V2DF  "")
419                                     (V1TI  "")
420                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
421                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
423 ; Iterator for 128-bit VSX types for pack/unpack
424 (define_mode_iterator FMOVE128_VSX [V1TI KF])
426 ; Whether a floating point move is ok, don't allow SD without hardware FP
427 (define_mode_attr fmove_ok [(SF "")
428                             (DF "")
429                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
430                             (DD "")])
432 ; Convert REAL_VALUE to the appropriate bits
433 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
434                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
435                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
436                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
438 ; Whether 0.0 has an all-zero bit pattern
439 (define_mode_attr zero_fp [(SF "j")
440                            (DF "j")
441                            (TF "j")
442                            (IF "j")
443                            (KF "j")
444                            (SD "wn")
445                            (DD "wn")
446                            (TD "wn")])
448 ; Definitions for load to 32-bit fpr register
449 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
450 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
451 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
452 (define_mode_attr f32_lm2 [(SF "wY")              (SD "wn")])
453 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
454 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
455 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
457 ; Definitions for store from 32-bit fpr register
458 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
459 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
460 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
461 (define_mode_attr f32_sm2 [(SF "wY")               (SD "wn")])
462 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
463 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
464 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwx %x1,%y0")])
466 ; Definitions for 32-bit fpr direct move
467 ; At present, the decimal modes are not allowed in the traditional altivec
468 ; registers, so restrict the constraints to just the traditional FPRs.
469 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
471 ; Definitions for 32-bit VSX
472 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
474 ; Definitions for 32-bit use of altivec registers
475 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
477 ; Definitions for 64-bit VSX
478 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
480 ; Definitions for 64-bit direct move
481 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
483 ; Definitions for 64-bit use of altivec registers
484 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
486 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
487 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
489 ; These modes do not fit in integer registers in 32-bit mode.
490 ; but on e500v2, the gpr are 64 bit registers
491 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
493 ; Iterator for reciprocal estimate instructions
494 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
496 ; Iterator for just SF/DF
497 (define_mode_iterator SFDF [SF DF])
499 ; Like SFDF, but a different name to match conditional move where the
500 ; comparison operands may be a different mode than the input operands.
501 (define_mode_iterator SFDF2 [SF DF])
503 ; Iterator for 128-bit floating point that uses the IBM double-double format
504 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
505                               (TF "FLOAT128_IBM_P (TFmode)")])
507 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
508 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
509                                (TF "FLOAT128_IEEE_P (TFmode)")])
511 ; Iterator for 128-bit floating point
512 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
513                                 (IF "TARGET_FLOAT128_TYPE")
514                                 (TF "TARGET_LONG_DOUBLE_128")])
516 ; Iterator for signbit on 64-bit machines with direct move
517 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
518                                (TF "FLOAT128_VECTOR_P (TFmode)")])
520 (define_mode_attr Fsignbit      [(KF "wa")
521                                  (TF "wa")])
523 ; Iterator for ISA 3.0 supported floating point types
524 (define_mode_iterator FP_ISA3 [SF
525                                DF
526                                (KF "FLOAT128_IEEE_P (KFmode)")
527                                (TF "FLOAT128_IEEE_P (TFmode)")])
529 ; SF/DF suffix for traditional floating instructions
530 (define_mode_attr Ftrad         [(SF "s") (DF "")])
532 ; SF/DF suffix for VSX instructions
533 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
535 ; SF/DF constraint for arithmetic on traditional floating point registers
536 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
538 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
539 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
540 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
541 ; format.
542 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
544 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
545 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
546 ; instructions added in ISA 2.07 (power8)
547 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
549 ; SF/DF constraint for arithmetic on altivec registers
550 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
552 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
553 (define_mode_attr Fs            [(SF "s")  (DF "d")])
555 ; FRE/FRES support
556 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
557 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
559 ; Conditional returns.
560 (define_code_iterator any_return [return simple_return])
561 (define_code_attr return_pred [(return "direct_return ()")
562                                (simple_return "1")])
563 (define_code_attr return_str [(return "") (simple_return "simple_")])
565 ; Logical operators.
566 (define_code_iterator iorxor [ior xor])
568 ; Signed/unsigned variants of ops.
569 (define_code_iterator any_extend        [sign_extend zero_extend])
570 (define_code_iterator any_fix           [fix unsigned_fix])
571 (define_code_iterator any_float         [float unsigned_float])
573 (define_code_attr u  [(sign_extend      "")
574                       (zero_extend      "u")])
576 (define_code_attr su [(sign_extend      "s")
577                       (zero_extend      "u")
578                       (fix              "s")
579                       (unsigned_fix     "s")
580                       (float            "s")
581                       (unsigned_float   "u")])
583 (define_code_attr az [(sign_extend      "a")
584                       (zero_extend      "z")
585                       (fix              "a")
586                       (unsigned_fix     "z")
587                       (float            "a")
588                       (unsigned_float   "z")])
590 (define_code_attr uns [(fix             "")
591                        (unsigned_fix    "uns")
592                        (float           "")
593                        (unsigned_float  "uns")])
595 ; Various instructions that come in SI and DI forms.
596 ; A generic w/d attribute, for things like cmpw/cmpd.
597 (define_mode_attr wd [(QI    "b")
598                       (HI    "h")
599                       (SI    "w")
600                       (DI    "d")
601                       (V16QI "b")
602                       (V8HI  "h")
603                       (V4SI  "w")
604                       (V2DI  "d")
605                       (V1TI  "q")
606                       (TI    "q")])
608 ;; How many bits in this mode?
609 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
611 ; DImode bits
612 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
614 ;; ISEL/ISEL64 target selection
615 (define_mode_attr sel [(SI "") (DI "64")])
617 ;; Bitmask for shift instructions
618 (define_mode_attr hH [(SI "h") (DI "H")])
620 ;; A mode twice the size of the given mode
621 (define_mode_attr dmode [(SI "di") (DI "ti")])
622 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
624 ;; Suffix for reload patterns
625 (define_mode_attr ptrsize [(SI "32bit")
626                            (DI "64bit")])
628 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
629                             (DI "TARGET_64BIT")])
631 (define_mode_attr mptrsize [(SI "si")
632                             (DI "di")])
634 (define_mode_attr ptrload [(SI "lwz")
635                            (DI "ld")])
637 (define_mode_attr ptrm [(SI "m")
638                         (DI "Y")])
640 (define_mode_attr rreg [(SF   "f")
641                         (DF   "ws")
642                         (TF   "f")
643                         (TD   "f")
644                         (V4SF "wf")
645                         (V2DF "wd")])
647 (define_mode_attr rreg2 [(SF   "f")
648                          (DF   "d")])
650 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
651                                  (DF "TARGET_FCFID")])
653 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
654                                 (DF "TARGET_E500_DOUBLE")])
656 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
657                                 (DF "TARGET_DOUBLE_FLOAT")])
659 ;; Mode iterator for logical operations on 128-bit types
660 (define_mode_iterator BOOL_128          [TI
661                                          PTI
662                                          (V16QI "TARGET_ALTIVEC")
663                                          (V8HI  "TARGET_ALTIVEC")
664                                          (V4SI  "TARGET_ALTIVEC")
665                                          (V4SF  "TARGET_ALTIVEC")
666                                          (V2DI  "TARGET_ALTIVEC")
667                                          (V2DF  "TARGET_ALTIVEC")
668                                          (V1TI  "TARGET_ALTIVEC")])
670 ;; For the GPRs we use 3 constraints for register outputs, two that are the
671 ;; same as the output register, and a third where the output register is an
672 ;; early clobber, so we don't have to deal with register overlaps.  For the
673 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
674 ;; either.
676 ;; Mode attribute for boolean operation register constraints for output
677 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
678                                          (PTI   "&r,r,r")
679                                          (V16QI "wa,v,&?r,?r,?r")
680                                          (V8HI  "wa,v,&?r,?r,?r")
681                                          (V4SI  "wa,v,&?r,?r,?r")
682                                          (V4SF  "wa,v,&?r,?r,?r")
683                                          (V2DI  "wa,v,&?r,?r,?r")
684                                          (V2DF  "wa,v,&?r,?r,?r")
685                                          (V1TI  "wa,v,&?r,?r,?r")])
687 ;; Mode attribute for boolean operation register constraints for operand1
688 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
689                                          (PTI   "r,0,r")
690                                          (V16QI "wa,v,r,0,r")
691                                          (V8HI  "wa,v,r,0,r")
692                                          (V4SI  "wa,v,r,0,r")
693                                          (V4SF  "wa,v,r,0,r")
694                                          (V2DI  "wa,v,r,0,r")
695                                          (V2DF  "wa,v,r,0,r")
696                                          (V1TI  "wa,v,r,0,r")])
698 ;; Mode attribute for boolean operation register constraints for operand2
699 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
700                                          (PTI   "r,r,0")
701                                          (V16QI "wa,v,r,r,0")
702                                          (V8HI  "wa,v,r,r,0")
703                                          (V4SI  "wa,v,r,r,0")
704                                          (V4SF  "wa,v,r,r,0")
705                                          (V2DI  "wa,v,r,r,0")
706                                          (V2DF  "wa,v,r,r,0")
707                                          (V1TI  "wa,v,r,r,0")])
709 ;; Mode attribute for boolean operation register constraints for operand1
710 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
711 ;; is used for operand1 or operand2
712 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
713                                          (PTI   "r,0,0")
714                                          (V16QI "wa,v,r,0,0")
715                                          (V8HI  "wa,v,r,0,0")
716                                          (V4SI  "wa,v,r,0,0")
717                                          (V4SF  "wa,v,r,0,0")
718                                          (V2DI  "wa,v,r,0,0")
719                                          (V2DF  "wa,v,r,0,0")
720                                          (V1TI  "wa,v,r,0,0")])
722 ;; Reload iterator for creating the function to allocate a base register to
723 ;; supplement addressing modes.
724 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
725                               SF SD SI DF DD DI TI PTI KF IF TF])
727 ;; Iterate over smin, smax
728 (define_code_iterator fp_minmax [smin smax])
730 (define_code_attr     minmax    [(smin "min")
731                                  (smax "max")])
733 (define_code_attr     SMINMAX   [(smin "SMIN")
734                                  (smax "SMAX")])
737 ;; Start with fixed-point load and store insns.  Here we put only the more
738 ;; complex forms.  Basic data transfer is done later.
740 (define_insn "zero_extendqi<mode>2"
741   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,?*wJwK,?*wK")
742         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,*wK")))]
743   ""
744   "@
745    lbz%U1%X1 %0,%1
746    rlwinm %0,%1,0,0xff
747    lxsibzx %x0,%y1
748    vextractub %0,%1,7"
749   [(set_attr "type" "load,shift,fpload,vecperm")])
751 (define_insn_and_split "*zero_extendqi<mode>2_dot"
752   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
753         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
754                     (const_int 0)))
755    (clobber (match_scratch:EXTQI 0 "=r,r"))]
756   "rs6000_gen_cell_microcode"
757   "@
758    andi. %0,%1,0xff
759    #"
760   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
761   [(set (match_dup 0)
762         (zero_extend:EXTQI (match_dup 1)))
763    (set (match_dup 2)
764         (compare:CC (match_dup 0)
765                     (const_int 0)))]
766   ""
767   [(set_attr "type" "logical")
768    (set_attr "dot" "yes")
769    (set_attr "length" "4,8")])
771 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
772   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
773         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
774                     (const_int 0)))
775    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
776         (zero_extend:EXTQI (match_dup 1)))]
777   "rs6000_gen_cell_microcode"
778   "@
779    andi. %0,%1,0xff
780    #"
781   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
782   [(set (match_dup 0)
783         (zero_extend:EXTQI (match_dup 1)))
784    (set (match_dup 2)
785         (compare:CC (match_dup 0)
786                     (const_int 0)))]
787   ""
788   [(set_attr "type" "logical")
789    (set_attr "dot" "yes")
790    (set_attr "length" "4,8")])
793 (define_insn "zero_extendhi<mode>2"
794   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wJwK,?*wK")
795         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
796   ""
797   "@
798    lhz%U1%X1 %0,%1
799    rlwinm %0,%1,0,0xffff
800    lxsihzx %x0,%y1
801    vextractuh %0,%1,6"
802   [(set_attr "type" "load,shift,fpload,vecperm")])
804 (define_insn_and_split "*zero_extendhi<mode>2_dot"
805   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
806         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
807                     (const_int 0)))
808    (clobber (match_scratch:EXTHI 0 "=r,r"))]
809   "rs6000_gen_cell_microcode"
810   "@
811    andi. %0,%1,0xffff
812    #"
813   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
814   [(set (match_dup 0)
815         (zero_extend:EXTHI (match_dup 1)))
816    (set (match_dup 2)
817         (compare:CC (match_dup 0)
818                     (const_int 0)))]
819   ""
820   [(set_attr "type" "logical")
821    (set_attr "dot" "yes")
822    (set_attr "length" "4,8")])
824 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
825   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
826         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
827                     (const_int 0)))
828    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
829         (zero_extend:EXTHI (match_dup 1)))]
830   "rs6000_gen_cell_microcode"
831   "@
832    andi. %0,%1,0xffff
833    #"
834   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
835   [(set (match_dup 0)
836         (zero_extend:EXTHI (match_dup 1)))
837    (set (match_dup 2)
838         (compare:CC (match_dup 0)
839                     (const_int 0)))]
840   ""
841   [(set_attr "type" "logical")
842    (set_attr "dot" "yes")
843    (set_attr "length" "4,8")])
846 (define_insn "zero_extendsi<mode>2"
847   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
848         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
849   ""
850   "@
851    lwz%U1%X1 %0,%1
852    rldicl %0,%1,0,32
853    lfiwzx %0,%y1
854    lxsiwzx %x0,%y1
855    mtvsrwz %x0,%1
856    mfvsrwz %0,%x1
857    xxextractuw %x0,%x1,1"
858   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
860 (define_insn_and_split "*zero_extendsi<mode>2_dot"
861   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
862         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
863                     (const_int 0)))
864    (clobber (match_scratch:EXTSI 0 "=r,r"))]
865   "rs6000_gen_cell_microcode"
866   "@
867    rldicl. %0,%1,0,32
868    #"
869   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
870   [(set (match_dup 0)
871         (zero_extend:DI (match_dup 1)))
872    (set (match_dup 2)
873         (compare:CC (match_dup 0)
874                     (const_int 0)))]
875   ""
876   [(set_attr "type" "shift")
877    (set_attr "dot" "yes")
878    (set_attr "length" "4,8")])
880 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
881   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
882         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
883                     (const_int 0)))
884    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
885         (zero_extend:EXTSI (match_dup 1)))]
886   "rs6000_gen_cell_microcode"
887   "@
888    rldicl. %0,%1,0,32
889    #"
890   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
891   [(set (match_dup 0)
892         (zero_extend:EXTSI (match_dup 1)))
893    (set (match_dup 2)
894         (compare:CC (match_dup 0)
895                     (const_int 0)))]
896   ""
897   [(set_attr "type" "shift")
898    (set_attr "dot" "yes")
899    (set_attr "length" "4,8")])
902 (define_insn "extendqi<mode>2"
903   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
904         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
905   ""
906   "@
907    extsb %0,%1
908    vextsb2d %0,%1"
909   [(set_attr "type" "exts,vecperm")])
911 (define_insn_and_split "*extendqi<mode>2_dot"
912   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
913         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
914                     (const_int 0)))
915    (clobber (match_scratch:EXTQI 0 "=r,r"))]
916   "rs6000_gen_cell_microcode"
917   "@
918    extsb. %0,%1
919    #"
920   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
921   [(set (match_dup 0)
922         (sign_extend:EXTQI (match_dup 1)))
923    (set (match_dup 2)
924         (compare:CC (match_dup 0)
925                     (const_int 0)))]
926   ""
927   [(set_attr "type" "exts")
928    (set_attr "dot" "yes")
929    (set_attr "length" "4,8")])
931 (define_insn_and_split "*extendqi<mode>2_dot2"
932   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
933         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
934                     (const_int 0)))
935    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
936         (sign_extend:EXTQI (match_dup 1)))]
937   "rs6000_gen_cell_microcode"
938   "@
939    extsb. %0,%1
940    #"
941   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
942   [(set (match_dup 0)
943         (sign_extend:EXTQI (match_dup 1)))
944    (set (match_dup 2)
945         (compare:CC (match_dup 0)
946                     (const_int 0)))]
947   ""
948   [(set_attr "type" "exts")
949    (set_attr "dot" "yes")
950    (set_attr "length" "4,8")])
953 (define_expand "extendhi<mode>2"
954   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
955         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
956   ""
957   "")
959 (define_insn "*extendhi<mode>2"
960   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
961         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
962   "rs6000_gen_cell_microcode"
963   "@
964    lha%U1%X1 %0,%1
965    extsh %0,%1
966    #
967    vextsh2d %0,%1"
968   [(set_attr "type" "load,exts,fpload,vecperm")
969    (set_attr "sign_extend" "yes")
970    (set_attr "length" "4,4,8,4")])
972 (define_split
973   [(set (match_operand:EXTHI 0 "altivec_register_operand")
974         (sign_extend:EXTHI
975          (match_operand:HI 1 "indexed_or_indirect_operand")))]
976   "TARGET_P9_VECTOR && reload_completed"
977   [(set (match_dup 2)
978         (match_dup 1))
979    (set (match_dup 0)
980         (sign_extend:EXTHI (match_dup 2)))]
982   operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
985 (define_insn "*extendhi<mode>2_noload"
986   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
987         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
988   "!rs6000_gen_cell_microcode"
989   "extsh %0,%1"
990   [(set_attr "type" "exts")])
992 (define_insn_and_split "*extendhi<mode>2_dot"
993   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
994         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
995                     (const_int 0)))
996    (clobber (match_scratch:EXTHI 0 "=r,r"))]
997   "rs6000_gen_cell_microcode"
998   "@
999    extsh. %0,%1
1000    #"
1001   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1002   [(set (match_dup 0)
1003         (sign_extend:EXTHI (match_dup 1)))
1004    (set (match_dup 2)
1005         (compare:CC (match_dup 0)
1006                     (const_int 0)))]
1007   ""
1008   [(set_attr "type" "exts")
1009    (set_attr "dot" "yes")
1010    (set_attr "length" "4,8")])
1012 (define_insn_and_split "*extendhi<mode>2_dot2"
1013   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1014         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1015                     (const_int 0)))
1016    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1017         (sign_extend:EXTHI (match_dup 1)))]
1018   "rs6000_gen_cell_microcode"
1019   "@
1020    extsh. %0,%1
1021    #"
1022   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1023   [(set (match_dup 0)
1024         (sign_extend:EXTHI (match_dup 1)))
1025    (set (match_dup 2)
1026         (compare:CC (match_dup 0)
1027                     (const_int 0)))]
1028   ""
1029   [(set_attr "type" "exts")
1030    (set_attr "dot" "yes")
1031    (set_attr "length" "4,8")])
1034 (define_insn "extendsi<mode>2"
1035   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1036         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1037   ""
1038   "@
1039    lwa%U1%X1 %0,%1
1040    extsw %0,%1
1041    lfiwax %0,%y1
1042    lxsiwax %x0,%y1
1043    mtvsrwa %x0,%1
1044    vextsw2d %0,%1"
1045   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1046    (set_attr "sign_extend" "yes")])
1048 (define_insn_and_split "*extendsi<mode>2_dot"
1049   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1050         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1051                     (const_int 0)))
1052    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1053   "rs6000_gen_cell_microcode"
1054   "@
1055    extsw. %0,%1
1056    #"
1057   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1058   [(set (match_dup 0)
1059         (sign_extend:EXTSI (match_dup 1)))
1060    (set (match_dup 2)
1061         (compare:CC (match_dup 0)
1062                     (const_int 0)))]
1063   ""
1064   [(set_attr "type" "exts")
1065    (set_attr "dot" "yes")
1066    (set_attr "length" "4,8")])
1068 (define_insn_and_split "*extendsi<mode>2_dot2"
1069   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1070         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1071                     (const_int 0)))
1072    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1073         (sign_extend:EXTSI (match_dup 1)))]
1074   "rs6000_gen_cell_microcode"
1075   "@
1076    extsw. %0,%1
1077    #"
1078   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1079   [(set (match_dup 0)
1080         (sign_extend:EXTSI (match_dup 1)))
1081    (set (match_dup 2)
1082         (compare:CC (match_dup 0)
1083                     (const_int 0)))]
1084   ""
1085   [(set_attr "type" "exts")
1086    (set_attr "dot" "yes")
1087    (set_attr "length" "4,8")])
1089 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1091 (define_insn "*macchwc"
1092   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1093         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1094                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1095                                        (const_int 16))
1096                                       (sign_extend:SI
1097                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1098                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1099                     (const_int 0)))
1100    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1101         (plus:SI (mult:SI (ashiftrt:SI
1102                            (match_dup 2)
1103                            (const_int 16))
1104                           (sign_extend:SI
1105                            (match_dup 1)))
1106                  (match_dup 4)))]
1107   "TARGET_MULHW"
1108   "macchw. %0,%1,%2"
1109   [(set_attr "type" "halfmul")])
1111 (define_insn "*macchw"
1112   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1113         (plus:SI (mult:SI (ashiftrt:SI
1114                            (match_operand:SI 2 "gpc_reg_operand" "r")
1115                            (const_int 16))
1116                           (sign_extend:SI
1117                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1118                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1119   "TARGET_MULHW"
1120   "macchw %0,%1,%2"
1121   [(set_attr "type" "halfmul")])
1123 (define_insn "*macchwuc"
1124   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1125         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1126                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1127                                        (const_int 16))
1128                                       (zero_extend:SI
1129                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1130                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1131                     (const_int 0)))
1132    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1133         (plus:SI (mult:SI (lshiftrt:SI
1134                            (match_dup 2)
1135                            (const_int 16))
1136                           (zero_extend:SI
1137                            (match_dup 1)))
1138                  (match_dup 4)))]
1139   "TARGET_MULHW"
1140   "macchwu. %0,%1,%2"
1141   [(set_attr "type" "halfmul")])
1143 (define_insn "*macchwu"
1144   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1145         (plus:SI (mult:SI (lshiftrt:SI
1146                            (match_operand:SI 2 "gpc_reg_operand" "r")
1147                            (const_int 16))
1148                           (zero_extend:SI
1149                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1150                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1151   "TARGET_MULHW"
1152   "macchwu %0,%1,%2"
1153   [(set_attr "type" "halfmul")])
1155 (define_insn "*machhwc"
1156   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1157         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1158                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1159                                        (const_int 16))
1160                                       (ashiftrt:SI
1161                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1162                                        (const_int 16)))
1163                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1164                     (const_int 0)))
1165    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1166         (plus:SI (mult:SI (ashiftrt:SI
1167                            (match_dup 1)
1168                            (const_int 16))
1169                           (ashiftrt:SI
1170                            (match_dup 2)
1171                            (const_int 16)))
1172                  (match_dup 4)))]
1173   "TARGET_MULHW"
1174   "machhw. %0,%1,%2"
1175   [(set_attr "type" "halfmul")])
1177 (define_insn "*machhw"
1178   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1179         (plus:SI (mult:SI (ashiftrt:SI
1180                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1181                            (const_int 16))
1182                           (ashiftrt:SI
1183                            (match_operand:SI 2 "gpc_reg_operand" "r")
1184                            (const_int 16)))
1185                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1186   "TARGET_MULHW"
1187   "machhw %0,%1,%2"
1188   [(set_attr "type" "halfmul")])
1190 (define_insn "*machhwuc"
1191   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1192         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1193                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1194                                        (const_int 16))
1195                                       (lshiftrt:SI
1196                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1197                                        (const_int 16)))
1198                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1199                     (const_int 0)))
1200    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1201         (plus:SI (mult:SI (lshiftrt:SI
1202                            (match_dup 1)
1203                            (const_int 16))
1204                           (lshiftrt:SI
1205                            (match_dup 2)
1206                            (const_int 16)))
1207                  (match_dup 4)))]
1208   "TARGET_MULHW"
1209   "machhwu. %0,%1,%2"
1210   [(set_attr "type" "halfmul")])
1212 (define_insn "*machhwu"
1213   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214         (plus:SI (mult:SI (lshiftrt:SI
1215                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1216                            (const_int 16))
1217                           (lshiftrt:SI
1218                            (match_operand:SI 2 "gpc_reg_operand" "r")
1219                            (const_int 16)))
1220                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1221   "TARGET_MULHW"
1222   "machhwu %0,%1,%2"
1223   [(set_attr "type" "halfmul")])
1225 (define_insn "*maclhwc"
1226   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1227         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1228                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1229                                       (sign_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 (sign_extend:SI
1235                            (match_dup 1))
1236                           (sign_extend:SI
1237                            (match_dup 2)))
1238                  (match_dup 4)))]
1239   "TARGET_MULHW"
1240   "maclhw. %0,%1,%2"
1241   [(set_attr "type" "halfmul")])
1243 (define_insn "*maclhw"
1244   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245         (plus:SI (mult:SI (sign_extend:SI
1246                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1247                           (sign_extend:SI
1248                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1249                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1250   "TARGET_MULHW"
1251   "maclhw %0,%1,%2"
1252   [(set_attr "type" "halfmul")])
1254 (define_insn "*maclhwuc"
1255   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1256         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1257                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1258                                       (zero_extend:SI
1259                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1260                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1261                     (const_int 0)))
1262    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1263         (plus:SI (mult:SI (zero_extend:SI
1264                            (match_dup 1))
1265                           (zero_extend:SI
1266                            (match_dup 2)))
1267                  (match_dup 4)))]
1268   "TARGET_MULHW"
1269   "maclhwu. %0,%1,%2"
1270   [(set_attr "type" "halfmul")])
1272 (define_insn "*maclhwu"
1273   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1274         (plus:SI (mult:SI (zero_extend:SI
1275                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1276                           (zero_extend:SI
1277                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1278                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1279   "TARGET_MULHW"
1280   "maclhwu %0,%1,%2"
1281   [(set_attr "type" "halfmul")])
1283 (define_insn "*nmacchwc"
1284   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1285         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1286                               (mult:SI (ashiftrt:SI
1287                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1288                                         (const_int 16))
1289                                        (sign_extend:SI
1290                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1291                     (const_int 0)))
1292    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293         (minus:SI (match_dup 4)
1294                   (mult:SI (ashiftrt:SI
1295                             (match_dup 2)
1296                             (const_int 16))
1297                            (sign_extend:SI
1298                             (match_dup 1)))))]
1299   "TARGET_MULHW"
1300   "nmacchw. %0,%1,%2"
1301   [(set_attr "type" "halfmul")])
1303 (define_insn "*nmacchw"
1304   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1305         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1306                   (mult:SI (ashiftrt:SI
1307                             (match_operand:SI 2 "gpc_reg_operand" "r")
1308                             (const_int 16))
1309                            (sign_extend:SI
1310                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1311   "TARGET_MULHW"
1312   "nmacchw %0,%1,%2"
1313   [(set_attr "type" "halfmul")])
1315 (define_insn "*nmachhwc"
1316   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1317         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1318                               (mult:SI (ashiftrt:SI
1319                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1320                                         (const_int 16))
1321                                        (ashiftrt:SI
1322                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1323                                         (const_int 16))))
1324                     (const_int 0)))
1325    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1326         (minus:SI (match_dup 4)
1327                   (mult:SI (ashiftrt:SI
1328                             (match_dup 1)
1329                             (const_int 16))
1330                            (ashiftrt:SI
1331                             (match_dup 2)
1332                             (const_int 16)))))]
1333   "TARGET_MULHW"
1334   "nmachhw. %0,%1,%2"
1335   [(set_attr "type" "halfmul")])
1337 (define_insn "*nmachhw"
1338   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1339         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1340                   (mult:SI (ashiftrt:SI
1341                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1342                             (const_int 16))
1343                            (ashiftrt:SI
1344                             (match_operand:SI 2 "gpc_reg_operand" "r")
1345                             (const_int 16)))))]
1346   "TARGET_MULHW"
1347   "nmachhw %0,%1,%2"
1348   [(set_attr "type" "halfmul")])
1350 (define_insn "*nmaclhwc"
1351   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1352         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1353                               (mult:SI (sign_extend:SI
1354                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1355                                        (sign_extend:SI
1356                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1357                     (const_int 0)))
1358    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359         (minus:SI (match_dup 4)
1360                   (mult:SI (sign_extend:SI
1361                             (match_dup 1))
1362                            (sign_extend:SI
1363                             (match_dup 2)))))]
1364   "TARGET_MULHW"
1365   "nmaclhw. %0,%1,%2"
1366   [(set_attr "type" "halfmul")])
1368 (define_insn "*nmaclhw"
1369   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1370         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1371                   (mult:SI (sign_extend:SI
1372                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1373                            (sign_extend:SI
1374                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1375   "TARGET_MULHW"
1376   "nmaclhw %0,%1,%2"
1377   [(set_attr "type" "halfmul")])
1379 (define_insn "*mulchwc"
1380   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1381         (compare:CC (mult:SI (ashiftrt:SI
1382                               (match_operand:SI 2 "gpc_reg_operand" "r")
1383                               (const_int 16))
1384                              (sign_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 (ashiftrt:SI
1389                   (match_dup 2)
1390                   (const_int 16))
1391                  (sign_extend:SI
1392                   (match_dup 1))))]
1393   "TARGET_MULHW"
1394   "mulchw. %0,%1,%2"
1395   [(set_attr "type" "halfmul")])
1397 (define_insn "*mulchw"
1398   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399         (mult:SI (ashiftrt:SI
1400                   (match_operand:SI 2 "gpc_reg_operand" "r")
1401                   (const_int 16))
1402                  (sign_extend:SI
1403                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1404   "TARGET_MULHW"
1405   "mulchw %0,%1,%2"
1406   [(set_attr "type" "halfmul")])
1408 (define_insn "*mulchwuc"
1409   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1410         (compare:CC (mult:SI (lshiftrt:SI
1411                               (match_operand:SI 2 "gpc_reg_operand" "r")
1412                               (const_int 16))
1413                              (zero_extend:SI
1414                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1415                     (const_int 0)))
1416    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1417         (mult:SI (lshiftrt:SI
1418                   (match_dup 2)
1419                   (const_int 16))
1420                  (zero_extend:SI
1421                   (match_dup 1))))]
1422   "TARGET_MULHW"
1423   "mulchwu. %0,%1,%2"
1424   [(set_attr "type" "halfmul")])
1426 (define_insn "*mulchwu"
1427   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1428         (mult:SI (lshiftrt:SI
1429                   (match_operand:SI 2 "gpc_reg_operand" "r")
1430                   (const_int 16))
1431                  (zero_extend:SI
1432                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1433   "TARGET_MULHW"
1434   "mulchwu %0,%1,%2"
1435   [(set_attr "type" "halfmul")])
1437 (define_insn "*mulhhwc"
1438   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1439         (compare:CC (mult:SI (ashiftrt:SI
1440                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1441                               (const_int 16))
1442                              (ashiftrt:SI
1443                               (match_operand:SI 2 "gpc_reg_operand" "r")
1444                               (const_int 16)))
1445                     (const_int 0)))
1446    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1447         (mult:SI (ashiftrt:SI
1448                   (match_dup 1)
1449                   (const_int 16))
1450                  (ashiftrt:SI
1451                   (match_dup 2)
1452                   (const_int 16))))]
1453   "TARGET_MULHW"
1454   "mulhhw. %0,%1,%2"
1455   [(set_attr "type" "halfmul")])
1457 (define_insn "*mulhhw"
1458   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1459         (mult:SI (ashiftrt:SI
1460                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1461                   (const_int 16))
1462                  (ashiftrt:SI
1463                   (match_operand:SI 2 "gpc_reg_operand" "r")
1464                   (const_int 16))))]
1465   "TARGET_MULHW"
1466   "mulhhw %0,%1,%2"
1467   [(set_attr "type" "halfmul")])
1469 (define_insn "*mulhhwuc"
1470   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1471         (compare:CC (mult:SI (lshiftrt:SI
1472                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1473                               (const_int 16))
1474                              (lshiftrt:SI
1475                               (match_operand:SI 2 "gpc_reg_operand" "r")
1476                               (const_int 16)))
1477                     (const_int 0)))
1478    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1479         (mult:SI (lshiftrt:SI
1480                   (match_dup 1)
1481                   (const_int 16))
1482                  (lshiftrt:SI
1483                   (match_dup 2)
1484                   (const_int 16))))]
1485   "TARGET_MULHW"
1486   "mulhhwu. %0,%1,%2"
1487   [(set_attr "type" "halfmul")])
1489 (define_insn "*mulhhwu"
1490   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491         (mult:SI (lshiftrt:SI
1492                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1493                   (const_int 16))
1494                  (lshiftrt:SI
1495                   (match_operand:SI 2 "gpc_reg_operand" "r")
1496                   (const_int 16))))]
1497   "TARGET_MULHW"
1498   "mulhhwu %0,%1,%2"
1499   [(set_attr "type" "halfmul")])
1501 (define_insn "*mullhwc"
1502   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1503         (compare:CC (mult:SI (sign_extend:SI
1504                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1505                              (sign_extend:SI
1506                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1507                     (const_int 0)))
1508    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1509         (mult:SI (sign_extend:SI
1510                   (match_dup 1))
1511                  (sign_extend:SI
1512                   (match_dup 2))))]
1513   "TARGET_MULHW"
1514   "mullhw. %0,%1,%2"
1515   [(set_attr "type" "halfmul")])
1517 (define_insn "*mullhw"
1518   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1519         (mult:SI (sign_extend:SI
1520                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1521                  (sign_extend:SI
1522                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1523   "TARGET_MULHW"
1524   "mullhw %0,%1,%2"
1525   [(set_attr "type" "halfmul")])
1527 (define_insn "*mullhwuc"
1528   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1529         (compare:CC (mult:SI (zero_extend:SI
1530                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1531                              (zero_extend:SI
1532                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1533                     (const_int 0)))
1534    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1535         (mult:SI (zero_extend:SI
1536                   (match_dup 1))
1537                  (zero_extend:SI
1538                   (match_dup 2))))]
1539   "TARGET_MULHW"
1540   "mullhwu. %0,%1,%2"
1541   [(set_attr "type" "halfmul")])
1543 (define_insn "*mullhwu"
1544   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1545         (mult:SI (zero_extend:SI
1546                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1547                  (zero_extend:SI
1548                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1549   "TARGET_MULHW"
1550   "mullhwu %0,%1,%2"
1551   [(set_attr "type" "halfmul")])
1553 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1554 (define_insn "dlmzb"
1555   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1556         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1557                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1558                    UNSPEC_DLMZB_CR))
1559    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1560         (unspec:SI [(match_dup 1)
1561                     (match_dup 2)]
1562                    UNSPEC_DLMZB))]
1563   "TARGET_DLMZB"
1564   "dlmzb. %0,%1,%2")
1566 (define_expand "strlensi"
1567   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1568         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1569                     (match_operand:QI 2 "const_int_operand" "")
1570                     (match_operand 3 "const_int_operand" "")]
1571                    UNSPEC_DLMZB_STRLEN))
1572    (clobber (match_scratch:CC 4 "=x"))]
1573   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1575   rtx result = operands[0];
1576   rtx src = operands[1];
1577   rtx search_char = operands[2];
1578   rtx align = operands[3];
1579   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1580   rtx loop_label, end_label, mem, cr0, cond;
1581   if (search_char != const0_rtx
1582       || GET_CODE (align) != CONST_INT
1583       || INTVAL (align) < 8)
1584         FAIL;
1585   word1 = gen_reg_rtx (SImode);
1586   word2 = gen_reg_rtx (SImode);
1587   scratch_dlmzb = gen_reg_rtx (SImode);
1588   scratch_string = gen_reg_rtx (Pmode);
1589   loop_label = gen_label_rtx ();
1590   end_label = gen_label_rtx ();
1591   addr = force_reg (Pmode, XEXP (src, 0));
1592   emit_move_insn (scratch_string, addr);
1593   emit_label (loop_label);
1594   mem = change_address (src, SImode, scratch_string);
1595   emit_move_insn (word1, mem);
1596   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1597   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1598   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1599   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1600   emit_jump_insn (gen_rtx_SET (pc_rtx,
1601                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1602                                                      cond,
1603                                                      gen_rtx_LABEL_REF
1604                                                        (VOIDmode,
1605                                                         end_label),
1606                                                      pc_rtx)));
1607   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1608   emit_jump_insn (gen_rtx_SET (pc_rtx,
1609                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1610   emit_barrier ();
1611   emit_label (end_label);
1612   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1613   emit_insn (gen_subsi3 (result, scratch_string, addr));
1614   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1615   DONE;
1618 ;; Fixed-point arithmetic insns.
1620 (define_expand "add<mode>3"
1621   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1622         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1623                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1624   ""
1626   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1627     {
1628       rtx lo0 = gen_lowpart (SImode, operands[0]);
1629       rtx lo1 = gen_lowpart (SImode, operands[1]);
1630       rtx lo2 = gen_lowpart (SImode, operands[2]);
1631       rtx hi0 = gen_highpart (SImode, operands[0]);
1632       rtx hi1 = gen_highpart (SImode, operands[1]);
1633       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1635       if (!reg_or_short_operand (lo2, SImode))
1636         lo2 = force_reg (SImode, lo2);
1637       if (!adde_operand (hi2, SImode))
1638         hi2 = force_reg (SImode, hi2);
1640       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1641       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1642       DONE;
1643     }
1645   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1646     {
1647       rtx tmp = ((!can_create_pseudo_p ()
1648                   || rtx_equal_p (operands[0], operands[1]))
1649                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1651       HOST_WIDE_INT val = INTVAL (operands[2]);
1652       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1653       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1655       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1656         FAIL;
1658       /* The ordering here is important for the prolog expander.
1659          When space is allocated from the stack, adding 'low' first may
1660          produce a temporary deallocation (which would be bad).  */
1661       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1662       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1663       DONE;
1664     }
1667 (define_insn "*add<mode>3"
1668   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1669         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1670                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1671   ""
1672   "@
1673    add %0,%1,%2
1674    addi %0,%1,%2
1675    addis %0,%1,%v2"
1676   [(set_attr "type" "add")])
1678 (define_insn "addsi3_high"
1679   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1680         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1681                  (high:SI (match_operand 2 "" ""))))]
1682   "TARGET_MACHO && !TARGET_64BIT"
1683   "addis %0,%1,ha16(%2)"
1684   [(set_attr "type" "add")])
1686 (define_insn_and_split "*add<mode>3_dot"
1687   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1688         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1689                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1690                     (const_int 0)))
1691    (clobber (match_scratch:GPR 0 "=r,r"))]
1692   "<MODE>mode == Pmode"
1693   "@
1694    add. %0,%1,%2
1695    #"
1696   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1697   [(set (match_dup 0)
1698         (plus:GPR (match_dup 1)
1699                  (match_dup 2)))
1700    (set (match_dup 3)
1701         (compare:CC (match_dup 0)
1702                     (const_int 0)))]
1703   ""
1704   [(set_attr "type" "add")
1705    (set_attr "dot" "yes")
1706    (set_attr "length" "4,8")])
1708 (define_insn_and_split "*add<mode>3_dot2"
1709   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1710         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1711                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1712                     (const_int 0)))
1713    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1714         (plus:GPR (match_dup 1)
1715                   (match_dup 2)))]
1716   "<MODE>mode == Pmode"
1717   "@
1718    add. %0,%1,%2
1719    #"
1720   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1721   [(set (match_dup 0)
1722         (plus:GPR (match_dup 1)
1723                   (match_dup 2)))
1724    (set (match_dup 3)
1725         (compare:CC (match_dup 0)
1726                     (const_int 0)))]
1727   ""
1728   [(set_attr "type" "add")
1729    (set_attr "dot" "yes")
1730    (set_attr "length" "4,8")])
1732 (define_insn_and_split "*add<mode>3_imm_dot"
1733   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1734         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1735                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1736                     (const_int 0)))
1737    (clobber (match_scratch:GPR 0 "=r,r"))
1738    (clobber (reg:GPR CA_REGNO))]
1739   "<MODE>mode == Pmode"
1740   "@
1741    addic. %0,%1,%2
1742    #"
1743   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1744   [(set (match_dup 0)
1745         (plus:GPR (match_dup 1)
1746                   (match_dup 2)))
1747    (set (match_dup 3)
1748         (compare:CC (match_dup 0)
1749                     (const_int 0)))]
1750   ""
1751   [(set_attr "type" "add")
1752    (set_attr "dot" "yes")
1753    (set_attr "length" "4,8")])
1755 (define_insn_and_split "*add<mode>3_imm_dot2"
1756   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1757         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1758                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1759                     (const_int 0)))
1760    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1761         (plus:GPR (match_dup 1)
1762                   (match_dup 2)))
1763    (clobber (reg:GPR CA_REGNO))]
1764   "<MODE>mode == Pmode"
1765   "@
1766    addic. %0,%1,%2
1767    #"
1768   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1769   [(set (match_dup 0)
1770         (plus:GPR (match_dup 1)
1771                   (match_dup 2)))
1772    (set (match_dup 3)
1773         (compare:CC (match_dup 0)
1774                     (const_int 0)))]
1775   ""
1776   [(set_attr "type" "add")
1777    (set_attr "dot" "yes")
1778    (set_attr "length" "4,8")])
1780 ;; Split an add that we can't do in one insn into two insns, each of which
1781 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1782 ;; add should be last in case the result gets used in an address.
1784 (define_split
1785   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1786         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1787                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1788   ""
1789   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1790    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1792   HOST_WIDE_INT val = INTVAL (operands[2]);
1793   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1794   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1796   operands[4] = GEN_INT (low);
1797   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1798     operands[3] = GEN_INT (rest);
1799   else if (can_create_pseudo_p ())
1800     {
1801       operands[3] = gen_reg_rtx (DImode);
1802       emit_move_insn (operands[3], operands[2]);
1803       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1804       DONE;
1805     }
1806   else
1807     FAIL;
1811 (define_insn "add<mode>3_carry"
1812   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1813         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1814                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1815    (set (reg:P CA_REGNO)
1816         (ltu:P (plus:P (match_dup 1)
1817                        (match_dup 2))
1818                (match_dup 1)))]
1819   ""
1820   "add%I2c %0,%1,%2"
1821   [(set_attr "type" "add")])
1823 (define_insn "*add<mode>3_imm_carry_pos"
1824   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1825         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1826                 (match_operand:P 2 "short_cint_operand" "n")))
1827    (set (reg:P CA_REGNO)
1828         (geu:P (match_dup 1)
1829                (match_operand:P 3 "const_int_operand" "n")))]
1830   "INTVAL (operands[2]) > 0
1831    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1832   "addic %0,%1,%2"
1833   [(set_attr "type" "add")])
1835 (define_insn "*add<mode>3_imm_carry_0"
1836   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1837         (match_operand:P 1 "gpc_reg_operand" "r"))
1838    (set (reg:P CA_REGNO)
1839         (const_int 0))]
1840   ""
1841   "addic %0,%1,0"
1842   [(set_attr "type" "add")])
1844 (define_insn "*add<mode>3_imm_carry_m1"
1845   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1846         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1847                 (const_int -1)))
1848    (set (reg:P CA_REGNO)
1849         (ne:P (match_dup 1)
1850               (const_int 0)))]
1851   ""
1852   "addic %0,%1,-1"
1853   [(set_attr "type" "add")])
1855 (define_insn "*add<mode>3_imm_carry_neg"
1856   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1857         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1858                 (match_operand:P 2 "short_cint_operand" "n")))
1859    (set (reg:P CA_REGNO)
1860         (gtu:P (match_dup 1)
1861                (match_operand:P 3 "const_int_operand" "n")))]
1862   "INTVAL (operands[2]) < 0
1863    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1864   "addic %0,%1,%2"
1865   [(set_attr "type" "add")])
1868 (define_expand "add<mode>3_carry_in"
1869   [(parallel [
1870      (set (match_operand:GPR 0 "gpc_reg_operand")
1871           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1872                               (match_operand:GPR 2 "adde_operand"))
1873                     (reg:GPR CA_REGNO)))
1874      (clobber (reg:GPR CA_REGNO))])]
1875   ""
1877   if (operands[2] == const0_rtx)
1878     {
1879       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1880       DONE;
1881     }
1882   if (operands[2] == constm1_rtx)
1883     {
1884       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1885       DONE;
1886     }
1889 (define_insn "*add<mode>3_carry_in_internal"
1890   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1891         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1892                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1893                   (reg:GPR CA_REGNO)))
1894    (clobber (reg:GPR CA_REGNO))]
1895   ""
1896   "adde %0,%1,%2"
1897   [(set_attr "type" "add")])
1899 (define_insn "add<mode>3_carry_in_0"
1900   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1901         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1902                   (reg:GPR CA_REGNO)))
1903    (clobber (reg:GPR CA_REGNO))]
1904   ""
1905   "addze %0,%1"
1906   [(set_attr "type" "add")])
1908 (define_insn "add<mode>3_carry_in_m1"
1909   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1910         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1911                             (reg:GPR CA_REGNO))
1912                   (const_int -1)))
1913    (clobber (reg:GPR CA_REGNO))]
1914   ""
1915   "addme %0,%1"
1916   [(set_attr "type" "add")])
1919 (define_expand "one_cmpl<mode>2"
1920   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1921         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1922   ""
1924   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1925     {
1926       rs6000_split_logical (operands, NOT, false, false, false);
1927       DONE;
1928     }
1931 (define_insn "*one_cmpl<mode>2"
1932   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1933         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1934   ""
1935   "not %0,%1")
1937 (define_insn_and_split "*one_cmpl<mode>2_dot"
1938   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1939         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1940                     (const_int 0)))
1941    (clobber (match_scratch:GPR 0 "=r,r"))]
1942   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1943   "@
1944    not. %0,%1
1945    #"
1946   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1947   [(set (match_dup 0)
1948         (not:GPR (match_dup 1)))
1949    (set (match_dup 2)
1950         (compare:CC (match_dup 0)
1951                     (const_int 0)))]
1952   ""
1953   [(set_attr "type" "logical")
1954    (set_attr "dot" "yes")
1955    (set_attr "length" "4,8")])
1957 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1958   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1959         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1960                     (const_int 0)))
1961    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1962         (not:GPR (match_dup 1)))]
1963   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1964   "@
1965    not. %0,%1
1966    #"
1967   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1968   [(set (match_dup 0)
1969         (not:GPR (match_dup 1)))
1970    (set (match_dup 2)
1971         (compare:CC (match_dup 0)
1972                     (const_int 0)))]
1973   ""
1974   [(set_attr "type" "logical")
1975    (set_attr "dot" "yes")
1976    (set_attr "length" "4,8")])
1979 (define_expand "sub<mode>3"
1980   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1981         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1982                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1983   ""
1985   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1986     {
1987       rtx lo0 = gen_lowpart (SImode, operands[0]);
1988       rtx lo1 = gen_lowpart (SImode, operands[1]);
1989       rtx lo2 = gen_lowpart (SImode, operands[2]);
1990       rtx hi0 = gen_highpart (SImode, operands[0]);
1991       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1992       rtx hi2 = gen_highpart (SImode, operands[2]);
1994       if (!reg_or_short_operand (lo1, SImode))
1995         lo1 = force_reg (SImode, lo1);
1996       if (!adde_operand (hi1, SImode))
1997         hi1 = force_reg (SImode, hi1);
1999       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2000       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2001       DONE;
2002     }
2004   if (short_cint_operand (operands[1], <MODE>mode))
2005     {
2006       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2007       DONE;
2008     }
2011 (define_insn "*subf<mode>3"
2012   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2013         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2014                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2015   ""
2016   "subf %0,%1,%2"
2017   [(set_attr "type" "add")])
2019 (define_insn_and_split "*subf<mode>3_dot"
2020   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2021         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2022                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2023                     (const_int 0)))
2024    (clobber (match_scratch:GPR 0 "=r,r"))]
2025   "<MODE>mode == Pmode"
2026   "@
2027    subf. %0,%1,%2
2028    #"
2029   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2030   [(set (match_dup 0)
2031         (minus:GPR (match_dup 2)
2032                    (match_dup 1)))
2033    (set (match_dup 3)
2034         (compare:CC (match_dup 0)
2035                     (const_int 0)))]
2036   ""
2037   [(set_attr "type" "add")
2038    (set_attr "dot" "yes")
2039    (set_attr "length" "4,8")])
2041 (define_insn_and_split "*subf<mode>3_dot2"
2042   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2043         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2044                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2045                     (const_int 0)))
2046    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2047         (minus:GPR (match_dup 2)
2048                    (match_dup 1)))]
2049   "<MODE>mode == Pmode"
2050   "@
2051    subf. %0,%1,%2
2052    #"
2053   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2054   [(set (match_dup 0)
2055         (minus:GPR (match_dup 2)
2056                    (match_dup 1)))
2057    (set (match_dup 3)
2058         (compare:CC (match_dup 0)
2059                     (const_int 0)))]
2060   ""
2061   [(set_attr "type" "add")
2062    (set_attr "dot" "yes")
2063    (set_attr "length" "4,8")])
2065 (define_insn "subf<mode>3_imm"
2066   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2067         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2068                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2069    (clobber (reg:GPR CA_REGNO))]
2070   ""
2071   "subfic %0,%1,%2"
2072   [(set_attr "type" "add")])
2075 (define_insn "subf<mode>3_carry"
2076   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2077         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2078                  (match_operand:P 1 "gpc_reg_operand" "r")))
2079    (set (reg:P CA_REGNO)
2080         (leu:P (match_dup 1)
2081                (match_dup 2)))]
2082   ""
2083   "subf%I2c %0,%1,%2"
2084   [(set_attr "type" "add")])
2086 (define_insn "*subf<mode>3_imm_carry_0"
2087   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2088         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2089    (set (reg:P CA_REGNO)
2090         (eq:P (match_dup 1)
2091               (const_int 0)))]
2092   ""
2093   "subfic %0,%1,0"
2094   [(set_attr "type" "add")])
2096 (define_insn "*subf<mode>3_imm_carry_m1"
2097   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2098         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2099    (set (reg:P CA_REGNO)
2100         (const_int 1))]
2101   ""
2102   "subfic %0,%1,-1"
2103   [(set_attr "type" "add")])
2106 (define_expand "subf<mode>3_carry_in"
2107   [(parallel [
2108      (set (match_operand:GPR 0 "gpc_reg_operand")
2109           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2110                               (reg:GPR CA_REGNO))
2111                     (match_operand:GPR 2 "adde_operand")))
2112      (clobber (reg:GPR CA_REGNO))])]
2113   ""
2115   if (operands[2] == const0_rtx)
2116     {
2117       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2118       DONE;
2119     }
2120   if (operands[2] == constm1_rtx)
2121     {
2122       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2123       DONE;
2124     }
2127 (define_insn "*subf<mode>3_carry_in_internal"
2128   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2129         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2130                             (reg:GPR CA_REGNO))
2131                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2132    (clobber (reg:GPR CA_REGNO))]
2133   ""
2134   "subfe %0,%1,%2"
2135   [(set_attr "type" "add")])
2137 (define_insn "subf<mode>3_carry_in_0"
2138   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2139         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2140                   (reg:GPR CA_REGNO)))
2141    (clobber (reg:GPR CA_REGNO))]
2142   ""
2143   "subfze %0,%1"
2144   [(set_attr "type" "add")])
2146 (define_insn "subf<mode>3_carry_in_m1"
2147   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2148         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2149                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2150                   (const_int -2)))
2151    (clobber (reg:GPR CA_REGNO))]
2152   ""
2153   "subfme %0,%1"
2154   [(set_attr "type" "add")])
2156 (define_insn "subf<mode>3_carry_in_xx"
2157   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2158         (plus:GPR (reg:GPR CA_REGNO)
2159                   (const_int -1)))
2160    (clobber (reg:GPR CA_REGNO))]
2161   ""
2162   "subfe %0,%0,%0"
2163   [(set_attr "type" "add")])
2166 (define_insn "neg<mode>2"
2167   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2168         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2169   ""
2170   "neg %0,%1"
2171   [(set_attr "type" "add")])
2173 (define_insn_and_split "*neg<mode>2_dot"
2174   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2175         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2176                     (const_int 0)))
2177    (clobber (match_scratch:GPR 0 "=r,r"))]
2178   "<MODE>mode == Pmode"
2179   "@
2180    neg. %0,%1
2181    #"
2182   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2183   [(set (match_dup 0)
2184         (neg:GPR (match_dup 1)))
2185    (set (match_dup 2)
2186         (compare:CC (match_dup 0)
2187                     (const_int 0)))]
2188   ""
2189   [(set_attr "type" "add")
2190    (set_attr "dot" "yes")
2191    (set_attr "length" "4,8")])
2193 (define_insn_and_split "*neg<mode>2_dot2"
2194   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2195         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2196                     (const_int 0)))
2197    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2198         (neg:GPR (match_dup 1)))]
2199   "<MODE>mode == Pmode"
2200   "@
2201    neg. %0,%1
2202    #"
2203   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2204   [(set (match_dup 0)
2205         (neg:GPR (match_dup 1)))
2206    (set (match_dup 2)
2207         (compare:CC (match_dup 0)
2208                     (const_int 0)))]
2209   ""
2210   [(set_attr "type" "add")
2211    (set_attr "dot" "yes")
2212    (set_attr "length" "4,8")])
2215 (define_insn "clz<mode>2"
2216   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2218   ""
2219   "cntlz<wd> %0,%1"
2220   [(set_attr "type" "cntlz")])
2222 (define_expand "ctz<mode>2"
2223   [(set (match_dup 2)
2224         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2225    (set (match_dup 3)
2226         (and:GPR (match_dup 1)
2227                  (match_dup 2)))
2228    (set (match_dup 4)
2229         (clz:GPR (match_dup 3)))
2230    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2231                    (minus:GPR (match_dup 5)
2232                               (match_dup 4)))
2233               (clobber (reg:GPR CA_REGNO))])]
2234   ""
2236   if (TARGET_CTZ)
2237     {
2238       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2239       DONE;
2240     }
2242   operands[2] = gen_reg_rtx (<MODE>mode);
2243   operands[3] = gen_reg_rtx (<MODE>mode);
2244   operands[4] = gen_reg_rtx (<MODE>mode);
2245   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2248 (define_insn "ctz<mode>2_hw"
2249   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2250         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2251   "TARGET_CTZ"
2252   "cnttz<wd> %0,%1"
2253   [(set_attr "type" "cntlz")])
2255 (define_expand "ffs<mode>2"
2256   [(set (match_dup 2)
2257         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2258    (set (match_dup 3)
2259         (and:GPR (match_dup 1)
2260                  (match_dup 2)))
2261    (set (match_dup 4)
2262         (clz:GPR (match_dup 3)))
2263    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2264                    (minus:GPR (match_dup 5)
2265                               (match_dup 4)))
2266               (clobber (reg:GPR CA_REGNO))])]
2267   ""
2269   operands[2] = gen_reg_rtx (<MODE>mode);
2270   operands[3] = gen_reg_rtx (<MODE>mode);
2271   operands[4] = gen_reg_rtx (<MODE>mode);
2272   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2276 (define_expand "popcount<mode>2"
2277   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2278         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2279   "TARGET_POPCNTB || TARGET_POPCNTD"
2281   rs6000_emit_popcount (operands[0], operands[1]);
2282   DONE;
2285 (define_insn "popcntb<mode>2"
2286   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2288                     UNSPEC_POPCNTB))]
2289   "TARGET_POPCNTB"
2290   "popcntb %0,%1"
2291   [(set_attr "type" "popcnt")])
2293 (define_insn "popcntd<mode>2"
2294   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2296   "TARGET_POPCNTD"
2297   "popcnt<wd> %0,%1"
2298   [(set_attr "type" "popcnt")])
2301 (define_expand "parity<mode>2"
2302   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2303         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2304   "TARGET_POPCNTB"
2306   rs6000_emit_parity (operands[0], operands[1]);
2307   DONE;
2310 (define_insn "parity<mode>2_cmpb"
2311   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2312         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2313   "TARGET_CMPB && TARGET_POPCNTB"
2314   "prty<wd> %0,%1"
2315   [(set_attr "type" "popcnt")])
2318 ;; Since the hardware zeros the upper part of the register, save generating the
2319 ;; AND immediate if we are converting to unsigned
2320 (define_insn "*bswaphi2_extenddi"
2321   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2322         (zero_extend:DI
2323          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2324   "TARGET_POWERPC64"
2325   "lhbrx %0,%y1"
2326   [(set_attr "length" "4")
2327    (set_attr "type" "load")])
2329 (define_insn "*bswaphi2_extendsi"
2330   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2331         (zero_extend:SI
2332          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2333   ""
2334   "lhbrx %0,%y1"
2335   [(set_attr "length" "4")
2336    (set_attr "type" "load")])
2338 (define_expand "bswaphi2"
2339   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2340                    (bswap:HI
2341                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2342               (clobber (match_scratch:SI 2 ""))])]
2343   ""
2345   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2346     operands[1] = force_reg (HImode, operands[1]);
2349 (define_insn "bswaphi2_internal"
2350   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2351         (bswap:HI
2352          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2353    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2354   ""
2355   "@
2356    lhbrx %0,%y1
2357    sthbrx %1,%y0
2358    #"
2359   [(set_attr "length" "4,4,12")
2360    (set_attr "type" "load,store,*")])
2362 (define_split
2363   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2364         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2365    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2366   "reload_completed"
2367   [(set (match_dup 3)
2368         (and:SI (lshiftrt:SI (match_dup 4)
2369                              (const_int 8))
2370                 (const_int 255)))
2371    (set (match_dup 2)
2372         (and:SI (ashift:SI (match_dup 4)
2373                            (const_int 8))
2374                 (const_int 65280)))             ;; 0xff00
2375    (set (match_dup 3)
2376         (ior:SI (match_dup 3)
2377                 (match_dup 2)))]
2378   "
2380   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2381   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2384 (define_insn "*bswapsi2_extenddi"
2385   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2386         (zero_extend:DI
2387          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2388   "TARGET_POWERPC64"
2389   "lwbrx %0,%y1"
2390   [(set_attr "length" "4")
2391    (set_attr "type" "load")])
2393 (define_expand "bswapsi2"
2394   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2395         (bswap:SI
2396          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2397   ""
2399   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2400     operands[1] = force_reg (SImode, operands[1]);
2403 (define_insn "*bswapsi2_internal"
2404   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2405         (bswap:SI
2406          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2407   ""
2408   "@
2409    lwbrx %0,%y1
2410    stwbrx %1,%y0
2411    #"
2412   [(set_attr "length" "4,4,12")
2413    (set_attr "type" "load,store,*")])
2415 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2416 ;; zero_extract insns do not change for -mlittle.
2417 (define_split
2418   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2419         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2420   "reload_completed"
2421   [(set (match_dup 0)                                   ; DABC
2422         (rotate:SI (match_dup 1)
2423                    (const_int 24)))
2424    (set (match_dup 0)                                   ; DCBC
2425         (ior:SI (and:SI (ashift:SI (match_dup 1)
2426                                    (const_int 8))
2427                         (const_int 16711680))
2428                 (and:SI (match_dup 0)
2429                         (const_int -16711681))))
2430    (set (match_dup 0)                                   ; DCBA
2431         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2432                                      (const_int 24))
2433                         (const_int 255))
2434                 (and:SI (match_dup 0)
2435                         (const_int -256))))
2437   ]
2438   "")
2440 (define_expand "bswapdi2"
2441   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2442                    (bswap:DI
2443                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2444               (clobber (match_scratch:DI 2 ""))
2445               (clobber (match_scratch:DI 3 ""))])]
2446   ""
2448   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2449     operands[1] = force_reg (DImode, operands[1]);
2451   if (!TARGET_POWERPC64)
2452     {
2453       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2454          that uses 64-bit registers needs the same scratch registers as 64-bit
2455          mode.  */
2456       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2457       DONE;
2458     }
2461 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2462 (define_insn "*bswapdi2_ldbrx"
2463   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2464         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2465    (clobber (match_scratch:DI 2 "=X,X,&r"))
2466    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2467   "TARGET_POWERPC64 && TARGET_LDBRX
2468    && (REG_P (operands[0]) || REG_P (operands[1]))"
2469   "@
2470    ldbrx %0,%y1
2471    stdbrx %1,%y0
2472    #"
2473   [(set_attr "length" "4,4,36")
2474    (set_attr "type" "load,store,*")])
2476 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2477 (define_insn "*bswapdi2_64bit"
2478   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2479         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2480    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2481    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2482   "TARGET_POWERPC64 && !TARGET_LDBRX
2483    && (REG_P (operands[0]) || REG_P (operands[1]))
2484    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2485    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2486   "#"
2487   [(set_attr "length" "16,12,36")])
2489 (define_split
2490   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2491         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2492    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2493    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2494   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2495   [(const_int 0)]
2496   "
2498   rtx dest   = operands[0];
2499   rtx src    = operands[1];
2500   rtx op2    = operands[2];
2501   rtx op3    = operands[3];
2502   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2503                                     BYTES_BIG_ENDIAN ? 4 : 0);
2504   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2505                                      BYTES_BIG_ENDIAN ? 4 : 0);
2506   rtx addr1;
2507   rtx addr2;
2508   rtx word1;
2509   rtx word2;
2511   addr1 = XEXP (src, 0);
2512   if (GET_CODE (addr1) == PLUS)
2513     {
2514       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2515       if (TARGET_AVOID_XFORM)
2516         {
2517           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2518           addr2 = op2;
2519         }
2520       else
2521         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2522     }
2523   else if (TARGET_AVOID_XFORM)
2524     {
2525       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2526       addr2 = op2;
2527     }
2528   else
2529     {
2530       emit_move_insn (op2, GEN_INT (4));
2531       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2532     }
2534   word1 = change_address (src, SImode, addr1);
2535   word2 = change_address (src, SImode, addr2);
2537   if (BYTES_BIG_ENDIAN)
2538     {
2539       emit_insn (gen_bswapsi2 (op3_32, word2));
2540       emit_insn (gen_bswapsi2 (dest_32, word1));
2541     }
2542   else
2543     {
2544       emit_insn (gen_bswapsi2 (op3_32, word1));
2545       emit_insn (gen_bswapsi2 (dest_32, word2));
2546     }
2548   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2549   emit_insn (gen_iordi3 (dest, dest, op3));
2550   DONE;
2553 (define_split
2554   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2555         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2556    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2557    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2558   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2559   [(const_int 0)]
2560   "
2562   rtx dest   = operands[0];
2563   rtx src    = operands[1];
2564   rtx op2    = operands[2];
2565   rtx op3    = operands[3];
2566   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2567                                     BYTES_BIG_ENDIAN ? 4 : 0);
2568   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2569                                     BYTES_BIG_ENDIAN ? 4 : 0);
2570   rtx addr1;
2571   rtx addr2;
2572   rtx word1;
2573   rtx word2;
2575   addr1 = XEXP (dest, 0);
2576   if (GET_CODE (addr1) == PLUS)
2577     {
2578       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2579       if (TARGET_AVOID_XFORM)
2580         {
2581           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2582           addr2 = op2;
2583         }
2584       else
2585         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2586     }
2587   else if (TARGET_AVOID_XFORM)
2588     {
2589       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2590       addr2 = op2;
2591     }
2592   else
2593     {
2594       emit_move_insn (op2, GEN_INT (4));
2595       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2596     }
2598   word1 = change_address (dest, SImode, addr1);
2599   word2 = change_address (dest, SImode, addr2);
2601   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2603   if (BYTES_BIG_ENDIAN)
2604     {
2605       emit_insn (gen_bswapsi2 (word1, src_si));
2606       emit_insn (gen_bswapsi2 (word2, op3_si));
2607     }
2608   else
2609     {
2610       emit_insn (gen_bswapsi2 (word2, src_si));
2611       emit_insn (gen_bswapsi2 (word1, op3_si));
2612     }
2613   DONE;
2616 (define_split
2617   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2618         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2619    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2620    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2621   "TARGET_POWERPC64 && reload_completed"
2622   [(const_int 0)]
2623   "
2625   rtx dest    = operands[0];
2626   rtx src     = operands[1];
2627   rtx op2     = operands[2];
2628   rtx op3     = operands[3];
2629   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2630   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2631   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2632   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2633   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2635   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2636   emit_insn (gen_bswapsi2 (dest_si, src_si));
2637   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2638   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2639   emit_insn (gen_iordi3 (dest, dest, op3));
2640   DONE;
2643 (define_insn "bswapdi2_32bit"
2644   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2645         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2646    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2647   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2648   "#"
2649   [(set_attr "length" "16,12,36")])
2651 (define_split
2652   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2653         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2654    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2655   "!TARGET_POWERPC64 && reload_completed"
2656   [(const_int 0)]
2657   "
2659   rtx dest  = operands[0];
2660   rtx src   = operands[1];
2661   rtx op2   = operands[2];
2662   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2663   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2664   rtx addr1;
2665   rtx addr2;
2666   rtx word1;
2667   rtx word2;
2669   addr1 = XEXP (src, 0);
2670   if (GET_CODE (addr1) == PLUS)
2671     {
2672       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2673       if (TARGET_AVOID_XFORM
2674           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2675         {
2676           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2677           addr2 = op2;
2678         }
2679       else
2680         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2681     }
2682   else if (TARGET_AVOID_XFORM
2683            || REGNO (addr1) == REGNO (dest2))
2684     {
2685       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2686       addr2 = op2;
2687     }
2688   else
2689     {
2690       emit_move_insn (op2, GEN_INT (4));
2691       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2692     }
2694   word1 = change_address (src, SImode, addr1);
2695   word2 = change_address (src, SImode, addr2);
2697   emit_insn (gen_bswapsi2 (dest2, word1));
2698   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2699      thus allowing us to omit an early clobber on the output.  */
2700   emit_insn (gen_bswapsi2 (dest1, word2));
2701   DONE;
2704 (define_split
2705   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2706         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2707    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2708   "!TARGET_POWERPC64 && reload_completed"
2709   [(const_int 0)]
2710   "
2712   rtx dest = operands[0];
2713   rtx src  = operands[1];
2714   rtx op2  = operands[2];
2715   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2716   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2717   rtx addr1;
2718   rtx addr2;
2719   rtx word1;
2720   rtx word2;
2722   addr1 = XEXP (dest, 0);
2723   if (GET_CODE (addr1) == PLUS)
2724     {
2725       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2726       if (TARGET_AVOID_XFORM)
2727         {
2728           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2729           addr2 = op2;
2730         }
2731       else
2732         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2733     }
2734   else if (TARGET_AVOID_XFORM)
2735     {
2736       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2737       addr2 = op2;
2738     }
2739   else
2740     {
2741       emit_move_insn (op2, GEN_INT (4));
2742       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2743     }
2745   word1 = change_address (dest, SImode, addr1);
2746   word2 = change_address (dest, SImode, addr2);
2748   emit_insn (gen_bswapsi2 (word2, src1));
2749   emit_insn (gen_bswapsi2 (word1, src2));
2750   DONE;
2753 (define_split
2754   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2755         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2756    (clobber (match_operand:SI 2 "" ""))]
2757   "!TARGET_POWERPC64 && reload_completed"
2758   [(const_int 0)]
2759   "
2761   rtx dest  = operands[0];
2762   rtx src   = operands[1];
2763   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2764   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2765   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2766   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2768   emit_insn (gen_bswapsi2 (dest1, src2));
2769   emit_insn (gen_bswapsi2 (dest2, src1));
2770   DONE;
2774 (define_insn "mul<mode>3"
2775   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2776         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2777                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2778   ""
2779   "@
2780    mull<wd> %0,%1,%2
2781    mulli %0,%1,%2"
2782    [(set_attr "type" "mul")
2783     (set (attr "size")
2784       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2785                 (const_string "8")
2786              (match_operand:GPR 2 "short_cint_operand" "")
2787                 (const_string "16")]
2788         (const_string "<bits>")))])
2790 (define_insn_and_split "*mul<mode>3_dot"
2791   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2792         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2793                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2794                     (const_int 0)))
2795    (clobber (match_scratch:GPR 0 "=r,r"))]
2796   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2797   "@
2798    mull<wd>. %0,%1,%2
2799    #"
2800   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2801   [(set (match_dup 0)
2802         (mult:GPR (match_dup 1)
2803                   (match_dup 2)))
2804    (set (match_dup 3)
2805         (compare:CC (match_dup 0)
2806                     (const_int 0)))]
2807   ""
2808   [(set_attr "type" "mul")
2809    (set_attr "size" "<bits>")
2810    (set_attr "dot" "yes")
2811    (set_attr "length" "4,8")])
2813 (define_insn_and_split "*mul<mode>3_dot2"
2814   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2815         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2816                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2817                     (const_int 0)))
2818    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2819         (mult:GPR (match_dup 1)
2820                   (match_dup 2)))]
2821   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2822   "@
2823    mull<wd>. %0,%1,%2
2824    #"
2825   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2826   [(set (match_dup 0)
2827         (mult:GPR (match_dup 1)
2828                   (match_dup 2)))
2829    (set (match_dup 3)
2830         (compare:CC (match_dup 0)
2831                     (const_int 0)))]
2832   ""
2833   [(set_attr "type" "mul")
2834    (set_attr "size" "<bits>")
2835    (set_attr "dot" "yes")
2836    (set_attr "length" "4,8")])
2839 (define_expand "<su>mul<mode>3_highpart"
2840   [(set (match_operand:GPR 0 "gpc_reg_operand")
2841         (subreg:GPR
2842           (mult:<DMODE> (any_extend:<DMODE>
2843                           (match_operand:GPR 1 "gpc_reg_operand"))
2844                         (any_extend:<DMODE>
2845                           (match_operand:GPR 2 "gpc_reg_operand")))
2846          0))]
2847   ""
2849   if (<MODE>mode == SImode && TARGET_POWERPC64)
2850     {
2851       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2852                                              operands[2]));
2853       DONE;
2854     }
2856   if (!WORDS_BIG_ENDIAN)
2857     {
2858       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2859                                                  operands[2]));
2860       DONE;
2861     }
2864 (define_insn "*<su>mul<mode>3_highpart"
2865   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2866         (subreg:GPR
2867           (mult:<DMODE> (any_extend:<DMODE>
2868                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2869                         (any_extend:<DMODE>
2870                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2871          0))]
2872   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2873   "mulh<wd><u> %0,%1,%2"
2874   [(set_attr "type" "mul")
2875    (set_attr "size" "<bits>")])
2877 (define_insn "<su>mulsi3_highpart_le"
2878   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2879         (subreg:SI
2880           (mult:DI (any_extend:DI
2881                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2882                    (any_extend:DI
2883                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2884          4))]
2885   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2886   "mulhw<u> %0,%1,%2"
2887   [(set_attr "type" "mul")])
2889 (define_insn "<su>muldi3_highpart_le"
2890   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2891         (subreg:DI
2892           (mult:TI (any_extend:TI
2893                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2894                    (any_extend:TI
2895                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2896          8))]
2897   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2898   "mulhd<u> %0,%1,%2"
2899   [(set_attr "type" "mul")
2900    (set_attr "size" "64")])
2902 (define_insn "<su>mulsi3_highpart_64"
2903   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2904         (truncate:SI
2905           (lshiftrt:DI
2906             (mult:DI (any_extend:DI
2907                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2908                      (any_extend:DI
2909                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2910             (const_int 32))))]
2911   "TARGET_POWERPC64"
2912   "mulhw<u> %0,%1,%2"
2913   [(set_attr "type" "mul")])
2915 (define_expand "<u>mul<mode><dmode>3"
2916   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2917         (mult:<DMODE> (any_extend:<DMODE>
2918                         (match_operand:GPR 1 "gpc_reg_operand"))
2919                       (any_extend:<DMODE>
2920                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2921   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2923   rtx l = gen_reg_rtx (<MODE>mode);
2924   rtx h = gen_reg_rtx (<MODE>mode);
2925   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2926   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2927   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2928   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2929   DONE;
2932 (define_insn "*maddld4"
2933   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2934         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2935                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2936                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2937   "TARGET_MADDLD"
2938   "maddld %0,%1,%2,%3"
2939   [(set_attr "type" "mul")])
2941 (define_insn "udiv<mode>3"
2942   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2943         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2944                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2945   ""
2946   "div<wd>u %0,%1,%2"
2947   [(set_attr "type" "div")
2948    (set_attr "size" "<bits>")])
2951 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2952 ;; modulus.  If it isn't a power of two, force operands into register and do
2953 ;; a normal divide.
2954 (define_expand "div<mode>3"
2955   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2956         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2957                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2958   ""
2960   if (CONST_INT_P (operands[2])
2961       && INTVAL (operands[2]) > 0
2962       && exact_log2 (INTVAL (operands[2])) >= 0)
2963     {
2964       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2965       DONE;
2966     }
2968   operands[2] = force_reg (<MODE>mode, operands[2]);
2971 (define_insn "*div<mode>3"
2972   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2973         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2974                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2975   ""
2976   "div<wd> %0,%1,%2"
2977   [(set_attr "type" "div")
2978    (set_attr "size" "<bits>")])
2980 (define_insn "div<mode>3_sra"
2981   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2982         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2983                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2984    (clobber (reg:GPR CA_REGNO))]
2985   ""
2986   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2987   [(set_attr "type" "two")
2988    (set_attr "length" "8")])
2990 (define_insn_and_split "*div<mode>3_sra_dot"
2991   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2992         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2993                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2994                     (const_int 0)))
2995    (clobber (match_scratch:GPR 0 "=r,r"))
2996    (clobber (reg:GPR CA_REGNO))]
2997   "<MODE>mode == Pmode"
2998   "@
2999    sra<wd>i %0,%1,%p2\;addze. %0,%0
3000    #"
3001   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3002   [(parallel [(set (match_dup 0)
3003                    (div:GPR (match_dup 1)
3004                             (match_dup 2)))
3005               (clobber (reg:GPR CA_REGNO))])
3006    (set (match_dup 3)
3007         (compare:CC (match_dup 0)
3008                     (const_int 0)))]
3009   ""
3010   [(set_attr "type" "two")
3011    (set_attr "length" "8,12")
3012    (set_attr "cell_micro" "not")])
3014 (define_insn_and_split "*div<mode>3_sra_dot2"
3015   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3016         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3017                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3018                     (const_int 0)))
3019    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3020         (div:GPR (match_dup 1)
3021                  (match_dup 2)))
3022    (clobber (reg:GPR CA_REGNO))]
3023   "<MODE>mode == Pmode"
3024   "@
3025    sra<wd>i %0,%1,%p2\;addze. %0,%0
3026    #"
3027   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3028   [(parallel [(set (match_dup 0)
3029                    (div:GPR (match_dup 1)
3030                             (match_dup 2)))
3031               (clobber (reg:GPR CA_REGNO))])
3032    (set (match_dup 3)
3033         (compare:CC (match_dup 0)
3034                     (const_int 0)))]
3035   ""
3036   [(set_attr "type" "two")
3037    (set_attr "length" "8,12")
3038    (set_attr "cell_micro" "not")])
3040 (define_expand "mod<mode>3"
3041   [(set (match_operand:GPR 0 "gpc_reg_operand")
3042         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3043                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3044   ""
3046   int i;
3047   rtx temp1;
3048   rtx temp2;
3050   if (GET_CODE (operands[2]) != CONST_INT
3051       || INTVAL (operands[2]) <= 0
3052       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3053     {
3054       if (!TARGET_MODULO)
3055         FAIL;
3057       operands[2] = force_reg (<MODE>mode, operands[2]);
3058     }
3059   else
3060     {
3061       temp1 = gen_reg_rtx (<MODE>mode);
3062       temp2 = gen_reg_rtx (<MODE>mode);
3064       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3065       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3066       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3067       DONE;
3068     }
3071 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3072 ;; mod, prefer putting the result of mod into a different register
3073 (define_insn "*mod<mode>3"
3074   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3075         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3076                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3077   "TARGET_MODULO"
3078   "mods<wd> %0,%1,%2"
3079   [(set_attr "type" "div")
3080    (set_attr "size" "<bits>")])
3083 (define_insn "umod<mode>3"
3084   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3085         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3086                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3087   "TARGET_MODULO"
3088   "modu<wd> %0,%1,%2"
3089   [(set_attr "type" "div")
3090    (set_attr "size" "<bits>")])
3092 ;; On machines with modulo support, do a combined div/mod the old fashioned
3093 ;; method, since the multiply/subtract is faster than doing the mod instruction
3094 ;; after a divide.
3096 (define_peephole2
3097   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3098         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3099                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3100    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3101         (mod:GPR (match_dup 1)
3102                  (match_dup 2)))]
3103   "TARGET_MODULO
3104    && ! reg_mentioned_p (operands[0], operands[1])
3105    && ! reg_mentioned_p (operands[0], operands[2])
3106    && ! reg_mentioned_p (operands[3], operands[1])
3107    && ! reg_mentioned_p (operands[3], operands[2])"
3108   [(set (match_dup 0)
3109         (div:GPR (match_dup 1)
3110                  (match_dup 2)))
3111    (set (match_dup 3)
3112         (mult:GPR (match_dup 0)
3113                   (match_dup 2)))
3114    (set (match_dup 3)
3115         (minus:GPR (match_dup 1)
3116                    (match_dup 3)))])
3118 (define_peephole2
3119   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3120         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3121                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3122    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3123         (umod:GPR (match_dup 1)
3124                   (match_dup 2)))]
3125   "TARGET_MODULO
3126    && ! reg_mentioned_p (operands[0], operands[1])
3127    && ! reg_mentioned_p (operands[0], operands[2])
3128    && ! reg_mentioned_p (operands[3], operands[1])
3129    && ! reg_mentioned_p (operands[3], operands[2])"
3130   [(set (match_dup 0)
3131         (div:GPR (match_dup 1)
3132                  (match_dup 2)))
3133    (set (match_dup 3)
3134         (mult:GPR (match_dup 0)
3135                   (match_dup 2)))
3136    (set (match_dup 3)
3137         (minus:GPR (match_dup 1)
3138                    (match_dup 3)))])
3141 ;; Logical instructions
3142 ;; The logical instructions are mostly combined by using match_operator,
3143 ;; but the plain AND insns are somewhat different because there is no
3144 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3145 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3147 (define_expand "and<mode>3"
3148   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3149         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3150                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3151   ""
3153   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3154     {
3155       rs6000_split_logical (operands, AND, false, false, false);
3156       DONE;
3157     }
3159   if (CONST_INT_P (operands[2]))
3160     {
3161       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3162         {
3163           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3164           DONE;
3165         }
3167       if (logical_const_operand (operands[2], <MODE>mode)
3168           && rs6000_gen_cell_microcode)
3169         {
3170           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3171           DONE;
3172         }
3174       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3175         {
3176           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3177           DONE;
3178         }
3180       operands[2] = force_reg (<MODE>mode, operands[2]);
3181     }
3185 (define_insn "and<mode>3_imm"
3186   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3187         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3188                  (match_operand:GPR 2 "logical_const_operand" "n")))
3189    (clobber (match_scratch:CC 3 "=x"))]
3190   "rs6000_gen_cell_microcode
3191    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3192   "andi%e2. %0,%1,%u2"
3193   [(set_attr "type" "logical")
3194    (set_attr "dot" "yes")])
3196 (define_insn_and_split "*and<mode>3_imm_dot"
3197   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3198         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3199                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3200                     (const_int 0)))
3201    (clobber (match_scratch:GPR 0 "=r,r"))
3202    (clobber (match_scratch:CC 4 "=X,x"))]
3203   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3204    && rs6000_gen_cell_microcode
3205    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3206   "@
3207    andi%e2. %0,%1,%u2
3208    #"
3209   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210   [(parallel [(set (match_dup 0)
3211                    (and:GPR (match_dup 1)
3212                             (match_dup 2)))
3213               (clobber (match_dup 4))])
3214    (set (match_dup 3)
3215         (compare:CC (match_dup 0)
3216                     (const_int 0)))]
3217   ""
3218   [(set_attr "type" "logical")
3219    (set_attr "dot" "yes")
3220    (set_attr "length" "4,8")])
3222 (define_insn_and_split "*and<mode>3_imm_dot2"
3223   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3224         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3225                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3226                     (const_int 0)))
3227    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3228         (and:GPR (match_dup 1)
3229                  (match_dup 2)))
3230    (clobber (match_scratch:CC 4 "=X,x"))]
3231   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3232    && rs6000_gen_cell_microcode
3233    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3234   "@
3235    andi%e2. %0,%1,%u2
3236    #"
3237   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3238   [(parallel [(set (match_dup 0)
3239                    (and:GPR (match_dup 1)
3240                             (match_dup 2)))
3241               (clobber (match_dup 4))])
3242    (set (match_dup 3)
3243         (compare:CC (match_dup 0)
3244                     (const_int 0)))]
3245   ""
3246   [(set_attr "type" "logical")
3247    (set_attr "dot" "yes")
3248    (set_attr "length" "4,8")])
3250 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3251   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3252         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3253                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3254                     (const_int 0)))
3255    (clobber (match_scratch:GPR 0 "=r,r"))]
3256   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3257    && rs6000_gen_cell_microcode"
3258   "@
3259    andi%e2. %0,%1,%u2
3260    #"
3261   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3262   [(set (match_dup 0)
3263         (and:GPR (match_dup 1)
3264                  (match_dup 2)))
3265    (set (match_dup 3)
3266         (compare:CC (match_dup 0)
3267                     (const_int 0)))]
3268   ""
3269   [(set_attr "type" "logical")
3270    (set_attr "dot" "yes")
3271    (set_attr "length" "4,8")])
3273 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3274   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3275         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3276                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3277                     (const_int 0)))
3278    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3279         (and:GPR (match_dup 1)
3280                  (match_dup 2)))]
3281   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3282    && rs6000_gen_cell_microcode"
3283   "@
3284    andi%e2. %0,%1,%u2
3285    #"
3286   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3287   [(set (match_dup 0)
3288         (and:GPR (match_dup 1)
3289                  (match_dup 2)))
3290    (set (match_dup 3)
3291         (compare:CC (match_dup 0)
3292                     (const_int 0)))]
3293   ""
3294   [(set_attr "type" "logical")
3295    (set_attr "dot" "yes")
3296    (set_attr "length" "4,8")])
3298 (define_insn "*and<mode>3_imm_dot_shifted"
3299   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3300         (compare:CC
3301           (and:GPR
3302             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3303                           (match_operand:SI 4 "const_int_operand" "n"))
3304             (match_operand:GPR 2 "const_int_operand" "n"))
3305           (const_int 0)))
3306    (clobber (match_scratch:GPR 0 "=r"))]
3307   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3308                                    << INTVAL (operands[4])),
3309                           DImode)
3310    && (<MODE>mode == Pmode
3311        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3312    && rs6000_gen_cell_microcode"
3314   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3315   return "andi%e2. %0,%1,%u2";
3317   [(set_attr "type" "logical")
3318    (set_attr "dot" "yes")])
3321 (define_insn "and<mode>3_mask"
3322   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3323         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3324                  (match_operand:GPR 2 "const_int_operand" "n")))]
3325   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3327   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3329   [(set_attr "type" "shift")])
3331 (define_insn_and_split "*and<mode>3_mask_dot"
3332   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3333         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3335                     (const_int 0)))
3336    (clobber (match_scratch:GPR 0 "=r,r"))]
3337   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338    && rs6000_gen_cell_microcode
3339    && !logical_const_operand (operands[2], <MODE>mode)
3340    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3342   if (which_alternative == 0)
3343     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3344   else
3345     return "#";
3347   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3348   [(set (match_dup 0)
3349         (and:GPR (match_dup 1)
3350                  (match_dup 2)))
3351    (set (match_dup 3)
3352         (compare:CC (match_dup 0)
3353                     (const_int 0)))]
3354   ""
3355   [(set_attr "type" "shift")
3356    (set_attr "dot" "yes")
3357    (set_attr "length" "4,8")])
3359 (define_insn_and_split "*and<mode>3_mask_dot2"
3360   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3361         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3362                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3363                     (const_int 0)))
3364    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3365         (and:GPR (match_dup 1)
3366                  (match_dup 2)))]
3367   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3368    && rs6000_gen_cell_microcode
3369    && !logical_const_operand (operands[2], <MODE>mode)
3370    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3372   if (which_alternative == 0)
3373     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3374   else
3375     return "#";
3377   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3378   [(set (match_dup 0)
3379         (and:GPR (match_dup 1)
3380                  (match_dup 2)))
3381    (set (match_dup 3)
3382         (compare:CC (match_dup 0)
3383                     (const_int 0)))]
3384   ""
3385   [(set_attr "type" "shift")
3386    (set_attr "dot" "yes")
3387    (set_attr "length" "4,8")])
3390 (define_insn_and_split "*and<mode>3_2insn"
3391   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3392         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3393                  (match_operand:GPR 2 "const_int_operand" "n")))]
3394   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3395    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3396         || (logical_const_operand (operands[2], <MODE>mode)
3397             && rs6000_gen_cell_microcode))"
3398   "#"
3399   "&& 1"
3400   [(pc)]
3402   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3403   DONE;
3405   [(set_attr "type" "shift")
3406    (set_attr "length" "8")])
3408 (define_insn_and_split "*and<mode>3_2insn_dot"
3409   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3410         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3411                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3412                     (const_int 0)))
3413    (clobber (match_scratch:GPR 0 "=r,r"))]
3414   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3415    && rs6000_gen_cell_microcode
3416    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3417    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3418         || (logical_const_operand (operands[2], <MODE>mode)
3419             && rs6000_gen_cell_microcode))"
3420   "#"
3421   "&& reload_completed"
3422   [(pc)]
3424   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3425   DONE;
3427   [(set_attr "type" "shift")
3428    (set_attr "dot" "yes")
3429    (set_attr "length" "8,12")])
3431 (define_insn_and_split "*and<mode>3_2insn_dot2"
3432   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3433         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3434                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3435                     (const_int 0)))
3436    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3437         (and:GPR (match_dup 1)
3438                  (match_dup 2)))]
3439   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3440    && rs6000_gen_cell_microcode
3441    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3442    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3443         || (logical_const_operand (operands[2], <MODE>mode)
3444             && rs6000_gen_cell_microcode))"
3445   "#"
3446   "&& reload_completed"
3447   [(pc)]
3449   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3450   DONE;
3452   [(set_attr "type" "shift")
3453    (set_attr "dot" "yes")
3454    (set_attr "length" "8,12")])
3457 (define_expand "<code><mode>3"
3458   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3459         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3460                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3461   ""
3463   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3464     {
3465       rs6000_split_logical (operands, <CODE>, false, false, false);
3466       DONE;
3467     }
3469   if (non_logical_cint_operand (operands[2], <MODE>mode))
3470     {
3471       rtx tmp = ((!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       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3480       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3481       DONE;
3482     }
3484   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3485     operands[2] = force_reg (<MODE>mode, operands[2]);
3488 (define_split
3489   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3490         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3491                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3492   ""
3493   [(set (match_dup 3)
3494         (iorxor:GPR (match_dup 1)
3495                     (match_dup 4)))
3496    (set (match_dup 0)
3497         (iorxor:GPR (match_dup 3)
3498                     (match_dup 5)))]
3500   operands[3] = ((!can_create_pseudo_p ()
3501                   || rtx_equal_p (operands[0], operands[1]))
3502                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3504   HOST_WIDE_INT value = INTVAL (operands[2]);
3505   HOST_WIDE_INT lo = value & 0xffff;
3506   HOST_WIDE_INT hi = value - lo;
3508   operands[4] = GEN_INT (hi);
3509   operands[5] = GEN_INT (lo);
3512 (define_insn "*bool<mode>3_imm"
3513   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3514         (match_operator:GPR 3 "boolean_or_operator"
3515          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3516           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3517   ""
3518   "%q3i%e2 %0,%1,%u2"
3519   [(set_attr "type" "logical")])
3521 (define_insn "*bool<mode>3"
3522   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3523         (match_operator:GPR 3 "boolean_operator"
3524          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3525           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3526   ""
3527   "%q3 %0,%1,%2"
3528   [(set_attr "type" "logical")])
3530 (define_insn_and_split "*bool<mode>3_dot"
3531   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3532         (compare:CC (match_operator:GPR 3 "boolean_operator"
3533          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3534           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3535          (const_int 0)))
3536    (clobber (match_scratch:GPR 0 "=r,r"))]
3537   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3538   "@
3539    %q3. %0,%1,%2
3540    #"
3541   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3542   [(set (match_dup 0)
3543         (match_dup 3))
3544    (set (match_dup 4)
3545         (compare:CC (match_dup 0)
3546                     (const_int 0)))]
3547   ""
3548   [(set_attr "type" "logical")
3549    (set_attr "dot" "yes")
3550    (set_attr "length" "4,8")])
3552 (define_insn_and_split "*bool<mode>3_dot2"
3553   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3554         (compare:CC (match_operator:GPR 3 "boolean_operator"
3555          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3556           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3557          (const_int 0)))
3558    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3559         (match_dup 3))]
3560   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3561   "@
3562    %q3. %0,%1,%2
3563    #"
3564   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3565   [(set (match_dup 0)
3566         (match_dup 3))
3567    (set (match_dup 4)
3568         (compare:CC (match_dup 0)
3569                     (const_int 0)))]
3570   ""
3571   [(set_attr "type" "logical")
3572    (set_attr "dot" "yes")
3573    (set_attr "length" "4,8")])
3576 (define_insn "*boolc<mode>3"
3577   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3578         (match_operator:GPR 3 "boolean_operator"
3579          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3580           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3581   ""
3582   "%q3 %0,%1,%2"
3583   [(set_attr "type" "logical")])
3585 (define_insn_and_split "*boolc<mode>3_dot"
3586   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3587         (compare:CC (match_operator:GPR 3 "boolean_operator"
3588          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3589           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3590          (const_int 0)))
3591    (clobber (match_scratch:GPR 0 "=r,r"))]
3592   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3593   "@
3594    %q3. %0,%1,%2
3595    #"
3596   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3597   [(set (match_dup 0)
3598         (match_dup 3))
3599    (set (match_dup 4)
3600         (compare:CC (match_dup 0)
3601                     (const_int 0)))]
3602   ""
3603   [(set_attr "type" "logical")
3604    (set_attr "dot" "yes")
3605    (set_attr "length" "4,8")])
3607 (define_insn_and_split "*boolc<mode>3_dot2"
3608   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3609         (compare:CC (match_operator:GPR 3 "boolean_operator"
3610          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3611           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3612          (const_int 0)))
3613    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3614         (match_dup 3))]
3615   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3616   "@
3617    %q3. %0,%1,%2
3618    #"
3619   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3620   [(set (match_dup 0)
3621         (match_dup 3))
3622    (set (match_dup 4)
3623         (compare:CC (match_dup 0)
3624                     (const_int 0)))]
3625   ""
3626   [(set_attr "type" "logical")
3627    (set_attr "dot" "yes")
3628    (set_attr "length" "4,8")])
3631 (define_insn "*boolcc<mode>3"
3632   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3633         (match_operator:GPR 3 "boolean_operator"
3634          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3635           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3636   ""
3637   "%q3 %0,%1,%2"
3638   [(set_attr "type" "logical")])
3640 (define_insn_and_split "*boolcc<mode>3_dot"
3641   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3642         (compare:CC (match_operator:GPR 3 "boolean_operator"
3643          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3644           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3645          (const_int 0)))
3646    (clobber (match_scratch:GPR 0 "=r,r"))]
3647   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3648   "@
3649    %q3. %0,%1,%2
3650    #"
3651   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3652   [(set (match_dup 0)
3653         (match_dup 3))
3654    (set (match_dup 4)
3655         (compare:CC (match_dup 0)
3656                     (const_int 0)))]
3657   ""
3658   [(set_attr "type" "logical")
3659    (set_attr "dot" "yes")
3660    (set_attr "length" "4,8")])
3662 (define_insn_and_split "*boolcc<mode>3_dot2"
3663   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3664         (compare:CC (match_operator:GPR 3 "boolean_operator"
3665          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3666           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3667          (const_int 0)))
3668    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3669         (match_dup 3))]
3670   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3671   "@
3672    %q3. %0,%1,%2
3673    #"
3674   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3675   [(set (match_dup 0)
3676         (match_dup 3))
3677    (set (match_dup 4)
3678         (compare:CC (match_dup 0)
3679                     (const_int 0)))]
3680   ""
3681   [(set_attr "type" "logical")
3682    (set_attr "dot" "yes")
3683    (set_attr "length" "4,8")])
3686 ;; TODO: Should have dots of this as well.
3687 (define_insn "*eqv<mode>3"
3688   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3689         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3690                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3691   ""
3692   "eqv %0,%1,%2"
3693   [(set_attr "type" "logical")])
3695 ;; Rotate-and-mask and insert.
3697 (define_insn "*rotl<mode>3_mask"
3698   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3699         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3700                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3701                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3702                  (match_operand:GPR 3 "const_int_operand" "n")))]
3703   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3705   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3707   [(set_attr "type" "shift")
3708    (set_attr "maybe_var_shift" "yes")])
3710 (define_insn_and_split "*rotl<mode>3_mask_dot"
3711   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3712         (compare:CC
3713           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3714                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3715                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3716                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3717           (const_int 0)))
3718    (clobber (match_scratch:GPR 0 "=r,r"))]
3719   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3720    && rs6000_gen_cell_microcode
3721    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3723   if (which_alternative == 0)
3724     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3725   else
3726     return "#";
3728   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3729   [(set (match_dup 0)
3730         (and:GPR (match_dup 4)
3731                  (match_dup 3)))
3732    (set (match_dup 5)
3733         (compare:CC (match_dup 0)
3734                     (const_int 0)))]
3735   ""
3736   [(set_attr "type" "shift")
3737    (set_attr "maybe_var_shift" "yes")
3738    (set_attr "dot" "yes")
3739    (set_attr "length" "4,8")])
3741 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3742   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3743         (compare:CC
3744           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3745                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3746                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3747                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3748           (const_int 0)))
3749    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3750         (and:GPR (match_dup 4)
3751                  (match_dup 3)))]
3752   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3753    && rs6000_gen_cell_microcode
3754    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3756   if (which_alternative == 0)
3757     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3758   else
3759     return "#";
3761   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3762   [(set (match_dup 0)
3763         (and:GPR (match_dup 4)
3764                  (match_dup 3)))
3765    (set (match_dup 5)
3766         (compare:CC (match_dup 0)
3767                     (const_int 0)))]
3768   ""
3769   [(set_attr "type" "shift")
3770    (set_attr "maybe_var_shift" "yes")
3771    (set_attr "dot" "yes")
3772    (set_attr "length" "4,8")])
3774 ; Special case for less-than-0.  We can do it with just one machine
3775 ; instruction, but the generic optimizers do not realise it is cheap.
3776 (define_insn "*lt0_disi"
3777   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3778         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3779                (const_int 0)))]
3780   "TARGET_POWERPC64"
3781   "rlwinm %0,%1,1,31,31"
3782   [(set_attr "type" "shift")])
3786 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3787 ; both are an AND so are the same precedence).
3788 (define_insn "*rotl<mode>3_insert"
3789   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3790         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3791                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3792                             (match_operand:SI 2 "const_int_operand" "n")])
3793                           (match_operand:GPR 3 "const_int_operand" "n"))
3794                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3795                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3796   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3797    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3799   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3801   [(set_attr "type" "insert")])
3802 ; FIXME: this needs an attr "size", so that the scheduler can see the
3803 ; difference between rlwimi and rldimi.  We also might want dot forms,
3804 ; but not for rlwimi on POWER4 and similar processors.
3806 (define_insn "*rotl<mode>3_insert_2"
3807   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3808         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3809                           (match_operand:GPR 6 "const_int_operand" "n"))
3810                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3811                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3812                             (match_operand:SI 2 "const_int_operand" "n")])
3813                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3814   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3815    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3817   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3819   [(set_attr "type" "insert")])
3821 ; There are also some forms without one of the ANDs.
3822 (define_insn "*rotl<mode>3_insert_3"
3823   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3824         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3825                           (match_operand:GPR 4 "const_int_operand" "n"))
3826                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3827                              (match_operand:SI 2 "const_int_operand" "n"))))]
3828   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3830   if (<MODE>mode == SImode)
3831     return "rlwimi %0,%1,%h2,0,31-%h2";
3832   else
3833     return "rldimi %0,%1,%H2,0";
3835   [(set_attr "type" "insert")])
3837 (define_insn "*rotl<mode>3_insert_4"
3838   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3839         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3840                           (match_operand:GPR 4 "const_int_operand" "n"))
3841                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3842                                (match_operand:SI 2 "const_int_operand" "n"))))]
3843   "<MODE>mode == SImode &&
3844    GET_MODE_PRECISION (<MODE>mode)
3845    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3847   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3848                          - INTVAL (operands[2]));
3849   if (<MODE>mode == SImode)
3850     return "rlwimi %0,%1,%h2,32-%h2,31";
3851   else
3852     return "rldimi %0,%1,%H2,64-%H2";
3854   [(set_attr "type" "insert")])
3856 (define_insn "*rotlsi3_insert_5"
3857   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3858         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3859                         (match_operand:SI 2 "const_int_operand" "n,n"))
3860                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3861                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3862   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3863    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3864    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3865   "@
3866    rlwimi %0,%3,0,%4
3867    rlwimi %0,%1,0,%2"
3868   [(set_attr "type" "insert")])
3870 (define_insn "*rotldi3_insert_6"
3871   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3872         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3873                         (match_operand:DI 2 "const_int_operand" "n"))
3874                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3875                         (match_operand:DI 4 "const_int_operand" "n"))))]
3876   "exact_log2 (-UINTVAL (operands[2])) > 0
3877    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3879   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3880   return "rldimi %0,%3,0,%5";
3882   [(set_attr "type" "insert")
3883    (set_attr "size" "64")])
3885 (define_insn "*rotldi3_insert_7"
3886   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3887         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3888                         (match_operand:DI 4 "const_int_operand" "n"))
3889                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3890                         (match_operand:DI 2 "const_int_operand" "n"))))]
3891   "exact_log2 (-UINTVAL (operands[2])) > 0
3892    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3894   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3895   return "rldimi %0,%3,0,%5";
3897   [(set_attr "type" "insert")
3898    (set_attr "size" "64")])
3901 ; This handles the important case of multiple-precision shifts.  There is
3902 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3903 (define_split
3904   [(set (match_operand:GPR 0 "gpc_reg_operand")
3905         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3906                              (match_operand:SI 3 "const_int_operand"))
3907                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3908                                (match_operand:SI 4 "const_int_operand"))))]
3909   "can_create_pseudo_p ()
3910    && INTVAL (operands[3]) + INTVAL (operands[4])
3911       >= GET_MODE_PRECISION (<MODE>mode)"
3912   [(set (match_dup 5)
3913         (lshiftrt:GPR (match_dup 2)
3914                       (match_dup 4)))
3915    (set (match_dup 0)
3916         (ior:GPR (and:GPR (match_dup 5)
3917                           (match_dup 6))
3918                  (ashift:GPR (match_dup 1)
3919                              (match_dup 3))))]
3921   unsigned HOST_WIDE_INT mask = 1;
3922   mask = (mask << INTVAL (operands[3])) - 1;
3923   operands[5] = gen_reg_rtx (<MODE>mode);
3924   operands[6] = GEN_INT (mask);
3927 (define_split
3928   [(set (match_operand:GPR 0 "gpc_reg_operand")
3929         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3930                                (match_operand:SI 4 "const_int_operand"))
3931                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3932                              (match_operand:SI 3 "const_int_operand"))))]
3933   "can_create_pseudo_p ()
3934    && INTVAL (operands[3]) + INTVAL (operands[4])
3935       >= GET_MODE_PRECISION (<MODE>mode)"
3936   [(set (match_dup 5)
3937         (lshiftrt:GPR (match_dup 2)
3938                       (match_dup 4)))
3939    (set (match_dup 0)
3940         (ior:GPR (and:GPR (match_dup 5)
3941                           (match_dup 6))
3942                  (ashift:GPR (match_dup 1)
3943                              (match_dup 3))))]
3945   unsigned HOST_WIDE_INT mask = 1;
3946   mask = (mask << INTVAL (operands[3])) - 1;
3947   operands[5] = gen_reg_rtx (<MODE>mode);
3948   operands[6] = GEN_INT (mask);
3952 ; Another important case is setting some bits to 1; we can do that with
3953 ; an insert instruction, in many cases.
3954 (define_insn_and_split "*ior<mode>_mask"
3955   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3956         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3957                  (match_operand:GPR 2 "const_int_operand" "n")))
3958    (clobber (match_scratch:GPR 3 "=r"))]
3959   "!logical_const_operand (operands[2], <MODE>mode)
3960    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3961   "#"
3962   "&& 1"
3963   [(set (match_dup 3)
3964         (const_int -1))
3965    (set (match_dup 0)
3966         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3967                                       (match_dup 4))
3968                           (match_dup 2))
3969                  (and:GPR (match_dup 1)
3970                           (match_dup 5))))]
3972   int nb, ne;
3973   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3974   if (GET_CODE (operands[3]) == SCRATCH)
3975     operands[3] = gen_reg_rtx (<MODE>mode);
3976   operands[4] = GEN_INT (ne);
3977   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3979   [(set_attr "type" "two")
3980    (set_attr "length" "8")])
3983 ;; Now the simple shifts.
3985 (define_insn "rotl<mode>3"
3986   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3987         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3988                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3989   ""
3990   "rotl<wd>%I2 %0,%1,%<hH>2"
3991   [(set_attr "type" "shift")
3992    (set_attr "maybe_var_shift" "yes")])
3994 (define_insn "*rotlsi3_64"
3995   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3996         (zero_extend:DI
3997             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3998                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3999   "TARGET_POWERPC64"
4000   "rotlw%I2 %0,%1,%h2"
4001   [(set_attr "type" "shift")
4002    (set_attr "maybe_var_shift" "yes")])
4004 (define_insn_and_split "*rotl<mode>3_dot"
4005   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4006         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4007                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4008                     (const_int 0)))
4009    (clobber (match_scratch:GPR 0 "=r,r"))]
4010   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4011   "@
4012    rotl<wd>%I2. %0,%1,%<hH>2
4013    #"
4014   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4015   [(set (match_dup 0)
4016         (rotate:GPR (match_dup 1)
4017                     (match_dup 2)))
4018    (set (match_dup 3)
4019         (compare:CC (match_dup 0)
4020                     (const_int 0)))]
4021   ""
4022   [(set_attr "type" "shift")
4023    (set_attr "maybe_var_shift" "yes")
4024    (set_attr "dot" "yes")
4025    (set_attr "length" "4,8")])
4027 (define_insn_and_split "*rotl<mode>3_dot2"
4028   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4029         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4030                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4031                     (const_int 0)))
4032    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4033         (rotate:GPR (match_dup 1)
4034                     (match_dup 2)))]
4035   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4036   "@
4037    rotl<wd>%I2. %0,%1,%<hH>2
4038    #"
4039   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4040   [(set (match_dup 0)
4041         (rotate:GPR (match_dup 1)
4042                     (match_dup 2)))
4043    (set (match_dup 3)
4044         (compare:CC (match_dup 0)
4045                     (const_int 0)))]
4046   ""
4047   [(set_attr "type" "shift")
4048    (set_attr "maybe_var_shift" "yes")
4049    (set_attr "dot" "yes")
4050    (set_attr "length" "4,8")])
4053 (define_insn "ashl<mode>3"
4054   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4055         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4056                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4057   ""
4058   "sl<wd>%I2 %0,%1,%<hH>2"
4059   [(set_attr "type" "shift")
4060    (set_attr "maybe_var_shift" "yes")])
4062 (define_insn "*ashlsi3_64"
4063   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4064         (zero_extend:DI
4065             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4066                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4067   "TARGET_POWERPC64"
4068   "slw%I2 %0,%1,%h2"
4069   [(set_attr "type" "shift")
4070    (set_attr "maybe_var_shift" "yes")])
4072 (define_insn_and_split "*ashl<mode>3_dot"
4073   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4074         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4075                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4076                     (const_int 0)))
4077    (clobber (match_scratch:GPR 0 "=r,r"))]
4078   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4079   "@
4080    sl<wd>%I2. %0,%1,%<hH>2
4081    #"
4082   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4083   [(set (match_dup 0)
4084         (ashift:GPR (match_dup 1)
4085                     (match_dup 2)))
4086    (set (match_dup 3)
4087         (compare:CC (match_dup 0)
4088                     (const_int 0)))]
4089   ""
4090   [(set_attr "type" "shift")
4091    (set_attr "maybe_var_shift" "yes")
4092    (set_attr "dot" "yes")
4093    (set_attr "length" "4,8")])
4095 (define_insn_and_split "*ashl<mode>3_dot2"
4096   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4097         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4098                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4099                     (const_int 0)))
4100    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4101         (ashift:GPR (match_dup 1)
4102                     (match_dup 2)))]
4103   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4104   "@
4105    sl<wd>%I2. %0,%1,%<hH>2
4106    #"
4107   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4108   [(set (match_dup 0)
4109         (ashift:GPR (match_dup 1)
4110                     (match_dup 2)))
4111    (set (match_dup 3)
4112         (compare:CC (match_dup 0)
4113                     (const_int 0)))]
4114   ""
4115   [(set_attr "type" "shift")
4116    (set_attr "maybe_var_shift" "yes")
4117    (set_attr "dot" "yes")
4118    (set_attr "length" "4,8")])
4120 ;; Pretend we have a memory form of extswsli until register allocation is done
4121 ;; so that we use LWZ to load the value from memory, instead of LWA.
4122 (define_insn_and_split "ashdi3_extswsli"
4123   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4124         (ashift:DI
4125          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4126          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4127   "TARGET_EXTSWSLI"
4128   "@
4129    extswsli %0,%1,%2
4130    #"
4131   "&& reload_completed && MEM_P (operands[1])"
4132   [(set (match_dup 3)
4133         (match_dup 1))
4134    (set (match_dup 0)
4135         (ashift:DI (sign_extend:DI (match_dup 3))
4136                    (match_dup 2)))]
4138   operands[3] = gen_lowpart (SImode, operands[0]);
4140   [(set_attr "type" "shift")
4141    (set_attr "maybe_var_shift" "no")])
4144 (define_insn_and_split "ashdi3_extswsli_dot"
4145   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4146         (compare:CC
4147          (ashift:DI
4148           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4149           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4150          (const_int 0)))
4151    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4152   "TARGET_EXTSWSLI"
4153   "@
4154    extswsli. %0,%1,%2
4155    #
4156    #
4157    #"
4158   "&& reload_completed
4159    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4160        || memory_operand (operands[1], SImode))"
4161   [(pc)]
4163   rtx dest = operands[0];
4164   rtx src = operands[1];
4165   rtx shift = operands[2];
4166   rtx cr = operands[3];
4167   rtx src2;
4169   if (!MEM_P (src))
4170     src2 = src;
4171   else
4172     {
4173       src2 = gen_lowpart (SImode, dest);
4174       emit_move_insn (src2, src);
4175     }
4177   if (REGNO (cr) == CR0_REGNO)
4178     {
4179       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4180       DONE;
4181     }
4183   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4184   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4185   DONE;
4187   [(set_attr "type" "shift")
4188    (set_attr "maybe_var_shift" "no")
4189    (set_attr "dot" "yes")
4190    (set_attr "length" "4,8,8,12")])
4192 (define_insn_and_split "ashdi3_extswsli_dot2"
4193   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4194         (compare:CC
4195          (ashift:DI
4196           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4197           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4198          (const_int 0)))
4199    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4200         (ashift:DI (sign_extend:DI (match_dup 1))
4201                    (match_dup 2)))]
4202   "TARGET_EXTSWSLI"
4203   "@
4204    extswsli. %0,%1,%2
4205    #
4206    #
4207    #"
4208   "&& reload_completed
4209    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4210        || memory_operand (operands[1], SImode))"
4211   [(pc)]
4213   rtx dest = operands[0];
4214   rtx src = operands[1];
4215   rtx shift = operands[2];
4216   rtx cr = operands[3];
4217   rtx src2;
4219   if (!MEM_P (src))
4220     src2 = src;
4221   else
4222     {
4223       src2 = gen_lowpart (SImode, dest);
4224       emit_move_insn (src2, src);
4225     }
4227   if (REGNO (cr) == CR0_REGNO)
4228     {
4229       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4230       DONE;
4231     }
4233   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4234   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4235   DONE;
4237   [(set_attr "type" "shift")
4238    (set_attr "maybe_var_shift" "no")
4239    (set_attr "dot" "yes")
4240    (set_attr "length" "4,8,8,12")])
4242 (define_insn "lshr<mode>3"
4243   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4244         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4245                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4246   ""
4247   "sr<wd>%I2 %0,%1,%<hH>2"
4248   [(set_attr "type" "shift")
4249    (set_attr "maybe_var_shift" "yes")])
4251 (define_insn "*lshrsi3_64"
4252   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4253         (zero_extend:DI
4254             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4255                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4256   "TARGET_POWERPC64"
4257   "srw%I2 %0,%1,%h2"
4258   [(set_attr "type" "shift")
4259    (set_attr "maybe_var_shift" "yes")])
4261 (define_insn_and_split "*lshr<mode>3_dot"
4262   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4263         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4264                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4265                     (const_int 0)))
4266    (clobber (match_scratch:GPR 0 "=r,r"))]
4267   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4268   "@
4269    sr<wd>%I2. %0,%1,%<hH>2
4270    #"
4271   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4272   [(set (match_dup 0)
4273         (lshiftrt:GPR (match_dup 1)
4274                       (match_dup 2)))
4275    (set (match_dup 3)
4276         (compare:CC (match_dup 0)
4277                     (const_int 0)))]
4278   ""
4279   [(set_attr "type" "shift")
4280    (set_attr "maybe_var_shift" "yes")
4281    (set_attr "dot" "yes")
4282    (set_attr "length" "4,8")])
4284 (define_insn_and_split "*lshr<mode>3_dot2"
4285   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4286         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4287                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4288                     (const_int 0)))
4289    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4290         (lshiftrt:GPR (match_dup 1)
4291                       (match_dup 2)))]
4292   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4293   "@
4294    sr<wd>%I2. %0,%1,%<hH>2
4295    #"
4296   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4297   [(set (match_dup 0)
4298         (lshiftrt:GPR (match_dup 1)
4299                       (match_dup 2)))
4300    (set (match_dup 3)
4301         (compare:CC (match_dup 0)
4302                     (const_int 0)))]
4303   ""
4304   [(set_attr "type" "shift")
4305    (set_attr "maybe_var_shift" "yes")
4306    (set_attr "dot" "yes")
4307    (set_attr "length" "4,8")])
4310 (define_insn "ashr<mode>3"
4311   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4312         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4313                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4314    (clobber (reg:GPR CA_REGNO))]
4315   ""
4316   "sra<wd>%I2 %0,%1,%<hH>2"
4317   [(set_attr "type" "shift")
4318    (set_attr "maybe_var_shift" "yes")])
4320 (define_insn "*ashrsi3_64"
4321   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4322         (sign_extend:DI
4323             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4324                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4325    (clobber (reg:SI CA_REGNO))]
4326   "TARGET_POWERPC64"
4327   "sraw%I2 %0,%1,%h2"
4328   [(set_attr "type" "shift")
4329    (set_attr "maybe_var_shift" "yes")])
4331 (define_insn_and_split "*ashr<mode>3_dot"
4332   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4333         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4334                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4335                     (const_int 0)))
4336    (clobber (match_scratch:GPR 0 "=r,r"))
4337    (clobber (reg:GPR CA_REGNO))]
4338   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4339   "@
4340    sra<wd>%I2. %0,%1,%<hH>2
4341    #"
4342   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4343   [(parallel [(set (match_dup 0)
4344                    (ashiftrt:GPR (match_dup 1)
4345                                  (match_dup 2)))
4346               (clobber (reg:GPR CA_REGNO))])
4347    (set (match_dup 3)
4348         (compare:CC (match_dup 0)
4349                     (const_int 0)))]
4350   ""
4351   [(set_attr "type" "shift")
4352    (set_attr "maybe_var_shift" "yes")
4353    (set_attr "dot" "yes")
4354    (set_attr "length" "4,8")])
4356 (define_insn_and_split "*ashr<mode>3_dot2"
4357   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4358         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4359                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4360                     (const_int 0)))
4361    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4362         (ashiftrt:GPR (match_dup 1)
4363                       (match_dup 2)))
4364    (clobber (reg:GPR CA_REGNO))]
4365   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4366   "@
4367    sra<wd>%I2. %0,%1,%<hH>2
4368    #"
4369   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4370   [(parallel [(set (match_dup 0)
4371                    (ashiftrt:GPR (match_dup 1)
4372                                  (match_dup 2)))
4373               (clobber (reg:GPR CA_REGNO))])
4374    (set (match_dup 3)
4375         (compare:CC (match_dup 0)
4376                     (const_int 0)))]
4377   ""
4378   [(set_attr "type" "shift")
4379    (set_attr "maybe_var_shift" "yes")
4380    (set_attr "dot" "yes")
4381    (set_attr "length" "4,8")])
4383 ;; Builtins to replace a division to generate FRE reciprocal estimate
4384 ;; instructions and the necessary fixup instructions
4385 (define_expand "recip<mode>3"
4386   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4387    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4388    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4389   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4391    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4392    DONE;
4395 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4396 ;; hardware division.  This is only done before register allocation and with
4397 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4398 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4399 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4400 (define_split
4401   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4402         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4403                     (match_operand 2 "gpc_reg_operand" "")))]
4404   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4405    && can_create_pseudo_p () && flag_finite_math_only
4406    && !flag_trapping_math && flag_reciprocal_math"
4407   [(const_int 0)]
4409   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4410   DONE;
4413 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4414 ;; appropriate fixup.
4415 (define_expand "rsqrt<mode>2"
4416   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4417    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4418   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4420   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4421   DONE;
4424 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4425 ;; modes here, and also add in conditional vsx/power8-vector support to access
4426 ;; values in the traditional Altivec registers if the appropriate
4427 ;; -mupper-regs-{df,sf} option is enabled.
4429 (define_expand "abs<mode>2"
4430   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4431         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4432   "TARGET_<MODE>_INSN"
4433   "")
4435 (define_insn "*abs<mode>2_fpr"
4436   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4437         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4438   "TARGET_<MODE>_FPR"
4439   "@
4440    fabs %0,%1
4441    xsabsdp %x0,%x1"
4442   [(set_attr "type" "fpsimple")
4443    (set_attr "fp_type" "fp_addsub_<Fs>")])
4445 (define_insn "*nabs<mode>2_fpr"
4446   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4447         (neg:SFDF
4448          (abs:SFDF
4449           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4450   "TARGET_<MODE>_FPR"
4451   "@
4452    fnabs %0,%1
4453    xsnabsdp %x0,%x1"
4454   [(set_attr "type" "fpsimple")
4455    (set_attr "fp_type" "fp_addsub_<Fs>")])
4457 (define_expand "neg<mode>2"
4458   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4459         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4460   "TARGET_<MODE>_INSN"
4461   "")
4463 (define_insn "*neg<mode>2_fpr"
4464   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4465         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4466   "TARGET_<MODE>_FPR"
4467   "@
4468    fneg %0,%1
4469    xsnegdp %x0,%x1"
4470   [(set_attr "type" "fpsimple")
4471    (set_attr "fp_type" "fp_addsub_<Fs>")])
4473 (define_expand "add<mode>3"
4474   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4475         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4476                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4477   "TARGET_<MODE>_INSN"
4478   "")
4480 (define_insn "*add<mode>3_fpr"
4481   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4482         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4483                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4484   "TARGET_<MODE>_FPR"
4485   "@
4486    fadd<Ftrad> %0,%1,%2
4487    xsadd<Fvsx> %x0,%x1,%x2"
4488   [(set_attr "type" "fp")
4489    (set_attr "fp_type" "fp_addsub_<Fs>")])
4491 (define_expand "sub<mode>3"
4492   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4493         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4494                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4495   "TARGET_<MODE>_INSN"
4496   "")
4498 (define_insn "*sub<mode>3_fpr"
4499   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4500         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4501                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4502   "TARGET_<MODE>_FPR"
4503   "@
4504    fsub<Ftrad> %0,%1,%2
4505    xssub<Fvsx> %x0,%x1,%x2"
4506   [(set_attr "type" "fp")
4507    (set_attr "fp_type" "fp_addsub_<Fs>")])
4509 (define_expand "mul<mode>3"
4510   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4511         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4512                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4513   "TARGET_<MODE>_INSN"
4514   "")
4516 (define_insn "*mul<mode>3_fpr"
4517   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4518         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4519                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4520   "TARGET_<MODE>_FPR"
4521   "@
4522    fmul<Ftrad> %0,%1,%2
4523    xsmul<Fvsx> %x0,%x1,%x2"
4524   [(set_attr "type" "dmul")
4525    (set_attr "fp_type" "fp_mul_<Fs>")])
4527 (define_expand "div<mode>3"
4528   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4529         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4530                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4531   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4533   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4534       && can_create_pseudo_p () && flag_finite_math_only
4535       && !flag_trapping_math && flag_reciprocal_math)
4536     {
4537       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4538       DONE;
4539     }
4542 (define_insn "*div<mode>3_fpr"
4543   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4544         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4545                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4546   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4547   "@
4548    fdiv<Ftrad> %0,%1,%2
4549    xsdiv<Fvsx> %x0,%x1,%x2"
4550   [(set_attr "type" "<Fs>div")
4551    (set_attr "fp_type" "fp_div_<Fs>")])
4553 (define_insn "*sqrt<mode>2_internal"
4554   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4555         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4556   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4557    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4558   "@
4559    fsqrt<Ftrad> %0,%1
4560    xssqrt<Fvsx> %x0,%x1"
4561   [(set_attr "type" "<Fs>sqrt")
4562    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4564 (define_expand "sqrt<mode>2"
4565   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4566         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4567   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4568    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4570   if (<MODE>mode == SFmode
4571       && TARGET_RECIP_PRECISION
4572       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4573       && !optimize_function_for_size_p (cfun)
4574       && flag_finite_math_only && !flag_trapping_math
4575       && flag_unsafe_math_optimizations)
4576     {
4577       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4578       DONE;
4579     }
4582 ;; Floating point reciprocal approximation
4583 (define_insn "fre<Fs>"
4584   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4585         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4586                      UNSPEC_FRES))]
4587   "TARGET_<FFRE>"
4588   "@
4589    fre<Ftrad> %0,%1
4590    xsre<Fvsx> %x0,%x1"
4591   [(set_attr "type" "fp")])
4593 (define_insn "*rsqrt<mode>2"
4594   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4595         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4596                      UNSPEC_RSQRT))]
4597   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4598   "@
4599    frsqrte<Ftrad> %0,%1
4600    xsrsqrte<Fvsx> %x0,%x1"
4601   [(set_attr "type" "fp")])
4603 ;; Floating point comparisons
4604 (define_insn "*cmp<mode>_fpr"
4605   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4606         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4607                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4608   "TARGET_<MODE>_FPR"
4609   "@
4610    fcmpu %0,%1,%2
4611    xscmpudp %0,%x1,%x2"
4612   [(set_attr "type" "fpcompare")])
4614 ;; Floating point conversions
4615 (define_expand "extendsfdf2"
4616   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4617         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4618   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4619   "")
4621 (define_insn_and_split "*extendsfdf2_fpr"
4622   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4623         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4624   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4625   "@
4626    #
4627    fmr %0,%1
4628    lfs%U1%X1 %0,%1
4629    #
4630    xscpsgndp %x0,%x1,%x1
4631    lxsspx %x0,%y1
4632    lxssp %0,%1"
4633   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4634   [(const_int 0)]
4636   emit_note (NOTE_INSN_DELETED);
4637   DONE;
4639   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4641 (define_expand "truncdfsf2"
4642   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4643         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4644   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4645   "")
4647 (define_insn "*truncdfsf2_fpr"
4648   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4649         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4650   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4651   "@
4652    frsp %0,%1
4653    xsrsp %x0,%x1"
4654   [(set_attr "type" "fp")])
4656 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4657 ;; builtins.c and optabs.c that are not correct for IBM long double
4658 ;; when little-endian.
4659 (define_expand "signbit<mode>2"
4660   [(set (match_dup 2)
4661         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4662    (set (match_dup 3)
4663         (subreg:DI (match_dup 2) 0))
4664    (set (match_dup 4)
4665         (match_dup 5))
4666    (set (match_operand:SI 0 "gpc_reg_operand" "")
4667         (match_dup 6))]
4668   "TARGET_HARD_FLOAT
4669    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4670    && (!FLOAT128_IEEE_P (<MODE>mode)
4671        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4673   if (FLOAT128_IEEE_P (<MODE>mode))
4674     {
4675       if (<MODE>mode == KFmode)
4676         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4677       else if (<MODE>mode == TFmode)
4678         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4679       else
4680         gcc_unreachable ();
4681       DONE;
4682     }
4683   operands[2] = gen_reg_rtx (DFmode);
4684   operands[3] = gen_reg_rtx (DImode);
4685   if (TARGET_POWERPC64)
4686     {
4687       operands[4] = gen_reg_rtx (DImode);
4688       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4689       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4690                                     WORDS_BIG_ENDIAN ? 4 : 0);
4691     }
4692   else
4693     {
4694       operands[4] = gen_reg_rtx (SImode);
4695       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4696                                     WORDS_BIG_ENDIAN ? 0 : 4);
4697       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4698     }
4701 (define_expand "copysign<mode>3"
4702   [(set (match_dup 3)
4703         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4704    (set (match_dup 4)
4705         (neg:SFDF (abs:SFDF (match_dup 1))))
4706    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4707         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4708                                (match_dup 5))
4709                          (match_dup 3)
4710                          (match_dup 4)))]
4711   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4712    && ((TARGET_PPC_GFXOPT
4713         && !HONOR_NANS (<MODE>mode)
4714         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4715        || TARGET_CMPB
4716        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4718   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4719     {
4720       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4721                                              operands[2]));
4722       DONE;
4723     }
4725    operands[3] = gen_reg_rtx (<MODE>mode);
4726    operands[4] = gen_reg_rtx (<MODE>mode);
4727    operands[5] = CONST0_RTX (<MODE>mode);
4728   })
4730 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4731 ;; and load.
4732 (define_insn_and_split "signbit<mode>2_dm"
4733   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4734         (unspec:SI
4735          [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4736          UNSPEC_SIGNBIT))]
4737   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4738   "#"
4739   "&& reload_completed"
4740   [(const_int 0)]
4742   rs6000_split_signbit (operands[0], operands[1]);
4743   DONE;
4745  [(set_attr "length" "8,8,12")
4746   (set_attr "type" "mftgpr,load,integer")])
4748 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4749 ;; point types, which makes normal SUBREG's problematical. Instead use a
4750 ;; special pattern to avoid using a normal movdi.
4751 (define_insn "signbit<mode>2_dm2"
4752   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4753         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4754                     (const_int 0)]
4755                    UNSPEC_SIGNBIT))]
4756   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4757   "mfvsrd %0,%x1"
4758  [(set_attr "type" "mftgpr")])
4761 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4762 ;; compiler from optimizing -0.0
4763 (define_insn "copysign<mode>3_fcpsgn"
4764   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4765         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4766                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4767                      UNSPEC_COPYSIGN))]
4768   "TARGET_<MODE>_FPR && TARGET_CMPB"
4769   "@
4770    fcpsgn %0,%2,%1
4771    xscpsgndp %x0,%x2,%x1"
4772   [(set_attr "type" "fpsimple")])
4774 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4775 ;; fsel instruction and some auxiliary computations.  Then we just have a
4776 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4777 ;; combine.
4778 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4779 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4780 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4781 ;; define_splits to make them if made by combine.  On VSX machines we have the
4782 ;; min/max instructions.
4784 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4785 ;; to allow either DF/SF to use only traditional registers.
4787 (define_expand "s<minmax><mode>3"
4788   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4789         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4790                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4791   "TARGET_MINMAX_<MODE>"
4793   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4794   DONE;
4797 (define_insn "*s<minmax><mode>3_vsx"
4798   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4799         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4800                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4801   "TARGET_VSX && TARGET_<MODE>_FPR"
4803   return (TARGET_P9_MINMAX
4804           ? "xs<minmax>cdp %x0,%x1,%x2"
4805           : "xs<minmax>dp %x0,%x1,%x2");
4807   [(set_attr "type" "fp")])
4809 ;; The conditional move instructions allow us to perform max and min operations
4810 ;; even when we don't have the appropriate max/min instruction using the FSEL
4811 ;; instruction.
4813 (define_insn_and_split "*s<minmax><mode>3_fpr"
4814   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4815         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4816                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4817   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4818   "#"
4819   "&& 1"
4820   [(const_int 0)]
4822   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4823   DONE;
4826 (define_expand "mov<mode>cc"
4827    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4828          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4829                            (match_operand:GPR 2 "gpc_reg_operand" "")
4830                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4831   "TARGET_ISEL<sel>"
4832   "
4834   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4835     DONE;
4836   else
4837     FAIL;
4840 ;; We use the BASE_REGS for the isel input operands because, if rA is
4841 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4842 ;; because we may switch the operands and rB may end up being rA.
4844 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4845 ;; leave out the mode in operand 4 and use one pattern, but reload can
4846 ;; change the mode underneath our feet and then gets confused trying
4847 ;; to reload the value.
4848 (define_insn "isel_signed_<mode>"
4849   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4850         (if_then_else:GPR
4851          (match_operator 1 "scc_comparison_operator"
4852                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4853                           (const_int 0)])
4854          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4855          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4856   "TARGET_ISEL<sel>"
4857   "*
4858 { return output_isel (operands); }"
4859   [(set_attr "type" "isel")
4860    (set_attr "length" "4")])
4862 (define_insn "isel_unsigned_<mode>"
4863   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4864         (if_then_else:GPR
4865          (match_operator 1 "scc_comparison_operator"
4866                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4867                           (const_int 0)])
4868          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4869          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4870   "TARGET_ISEL<sel>"
4871   "*
4872 { return output_isel (operands); }"
4873   [(set_attr "type" "isel")
4874    (set_attr "length" "4")])
4876 ;; These patterns can be useful for combine; they let combine know that
4877 ;; isel can handle reversed comparisons so long as the operands are
4878 ;; registers.
4880 (define_insn "*isel_reversed_signed_<mode>"
4881   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4882         (if_then_else:GPR
4883          (match_operator 1 "scc_rev_comparison_operator"
4884                          [(match_operand:CC 4 "cc_reg_operand" "y")
4885                           (const_int 0)])
4886          (match_operand:GPR 2 "gpc_reg_operand" "b")
4887          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4888   "TARGET_ISEL<sel>"
4889   "*
4890 { return output_isel (operands); }"
4891   [(set_attr "type" "isel")
4892    (set_attr "length" "4")])
4894 (define_insn "*isel_reversed_unsigned_<mode>"
4895   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4896         (if_then_else:GPR
4897          (match_operator 1 "scc_rev_comparison_operator"
4898                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4899                           (const_int 0)])
4900          (match_operand:GPR 2 "gpc_reg_operand" "b")
4901          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4902   "TARGET_ISEL<sel>"
4903   "*
4904 { return output_isel (operands); }"
4905   [(set_attr "type" "isel")
4906    (set_attr "length" "4")])
4908 ;; Floating point conditional move
4909 (define_expand "mov<mode>cc"
4910    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4911          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4912                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4913                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4914   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4915   "
4917   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4918     DONE;
4919   else
4920     FAIL;
4923 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4924   [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4925         (if_then_else:SFDF
4926          (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4927              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4928          (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4929          (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4930   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4931   "fsel %0,%1,%2,%3"
4932   [(set_attr "type" "fp")])
4934 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4935   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4936         (if_then_else:SFDF
4937          (match_operator:CCFP 1 "fpmask_comparison_operator"
4938                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4939                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4940          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4941          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4942    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4943   "TARGET_P9_MINMAX"
4944   "#"
4945   ""
4946   [(set (match_dup 6)
4947         (if_then_else:V2DI (match_dup 1)
4948                            (match_dup 7)
4949                            (match_dup 8)))
4950    (set (match_dup 0)
4951         (if_then_else:SFDF (ne (match_dup 6)
4952                                (match_dup 8))
4953                            (match_dup 4)
4954                            (match_dup 5)))]
4956   if (GET_CODE (operands[6]) == SCRATCH)
4957     operands[6] = gen_reg_rtx (V2DImode);
4959   operands[7] = CONSTM1_RTX (V2DImode);
4960   operands[8] = CONST0_RTX (V2DImode);
4962  [(set_attr "length" "8")
4963   (set_attr "type" "vecperm")])
4965 ;; Handle inverting the fpmask comparisons.
4966 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4967   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4968         (if_then_else:SFDF
4969          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4970                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4971                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4972          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4973          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4974    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4975   "TARGET_P9_MINMAX"
4976   "#"
4977   "&& 1"
4978   [(set (match_dup 6)
4979         (if_then_else:V2DI (match_dup 9)
4980                            (match_dup 7)
4981                            (match_dup 8)))
4982    (set (match_dup 0)
4983         (if_then_else:SFDF (ne (match_dup 6)
4984                                (match_dup 8))
4985                            (match_dup 5)
4986                            (match_dup 4)))]
4988   rtx op1 = operands[1];
4989   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
4991   if (GET_CODE (operands[6]) == SCRATCH)
4992     operands[6] = gen_reg_rtx (V2DImode);
4994   operands[7] = CONSTM1_RTX (V2DImode);
4995   operands[8] = CONST0_RTX (V2DImode);
4997   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
4999  [(set_attr "length" "8")
5000   (set_attr "type" "vecperm")])
5002 (define_insn "*fpmask<mode>"
5003   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5004         (if_then_else:V2DI
5005          (match_operator:CCFP 1 "fpmask_comparison_operator"
5006                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5007                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5008          (match_operand:V2DI 4 "all_ones_constant" "")
5009          (match_operand:V2DI 5 "zero_constant" "")))]
5010   "TARGET_P9_MINMAX"
5011   "xscmp%V1dp %x0,%x2,%x3"
5012   [(set_attr "type" "fpcompare")])
5014 (define_insn "*xxsel<mode>"
5015   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5016         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5017                                (match_operand:V2DI 2 "zero_constant" ""))
5018                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5019                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5020   "TARGET_P9_MINMAX"
5021   "xxsel %x0,%x4,%x3,%x1"
5022   [(set_attr "type" "vecmove")])
5025 ;; Conversions to and from floating-point.
5027 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5028 ; don't want to support putting SImode in FPR registers.
5029 (define_insn "lfiwax"
5030   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5031         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5032                    UNSPEC_LFIWAX))]
5033   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5034   "@
5035    lfiwax %0,%y1
5036    lxsiwax %x0,%y1
5037    mtvsrwa %x0,%1
5038    vextsw2d %0,%1"
5039   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5041 ; This split must be run before register allocation because it allocates the
5042 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5043 ; it earlier to allow for the combiner to merge insns together where it might
5044 ; not be needed and also in case the insns are deleted as dead code.
5046 (define_insn_and_split "floatsi<mode>2_lfiwax"
5047   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5048         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5049    (clobber (match_scratch:DI 2 "=wi"))]
5050   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5051    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5052   "#"
5053   ""
5054   [(pc)]
5055   "
5057   rtx dest = operands[0];
5058   rtx src = operands[1];
5059   rtx tmp;
5061   if (!MEM_P (src) && TARGET_POWERPC64
5062       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5063     tmp = convert_to_mode (DImode, src, false);
5064   else
5065     {
5066       tmp = operands[2];
5067       if (GET_CODE (tmp) == SCRATCH)
5068         tmp = gen_reg_rtx (DImode);
5069       if (MEM_P (src))
5070         {
5071           src = rs6000_address_for_fpconvert (src);
5072           emit_insn (gen_lfiwax (tmp, src));
5073         }
5074       else
5075         {
5076           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5077           emit_move_insn (stack, src);
5078           emit_insn (gen_lfiwax (tmp, stack));
5079         }
5080     }
5081   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5082   DONE;
5084   [(set_attr "length" "12")
5085    (set_attr "type" "fpload")])
5087 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5088   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5089         (float:SFDF
5090          (sign_extend:DI
5091           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5092    (clobber (match_scratch:DI 2 "=wi"))]
5093   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5094    && <SI_CONVERT_FP>"
5095   "#"
5096   ""
5097   [(pc)]
5098   "
5100   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5101   if (GET_CODE (operands[2]) == SCRATCH)
5102     operands[2] = gen_reg_rtx (DImode);
5103   if (TARGET_VSX_SMALL_INTEGER)
5104     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5105   else
5106     emit_insn (gen_lfiwax (operands[2], operands[1]));
5107   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5108   DONE;
5110   [(set_attr "length" "8")
5111    (set_attr "type" "fpload")])
5113 (define_insn "lfiwzx"
5114   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5115         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5116                    UNSPEC_LFIWZX))]
5117   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5118   "@
5119    lfiwzx %0,%y1
5120    lxsiwzx %x0,%y1
5121    mtvsrwz %x0,%1
5122    xxextractuw %x0,%x1,1"
5123   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5125 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5126   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5127         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5128    (clobber (match_scratch:DI 2 "=wi"))]
5129   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5130    && <SI_CONVERT_FP>"
5131   "#"
5132   ""
5133   [(pc)]
5134   "
5136   rtx dest = operands[0];
5137   rtx src = operands[1];
5138   rtx tmp;
5140   if (!MEM_P (src) && TARGET_POWERPC64
5141       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5142     tmp = convert_to_mode (DImode, src, true);
5143   else
5144     {
5145       tmp = operands[2];
5146       if (GET_CODE (tmp) == SCRATCH)
5147         tmp = gen_reg_rtx (DImode);
5148       if (MEM_P (src))
5149         {
5150           src = rs6000_address_for_fpconvert (src);
5151           emit_insn (gen_lfiwzx (tmp, src));
5152         }
5153       else
5154         {
5155           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5156           emit_move_insn (stack, src);
5157           emit_insn (gen_lfiwzx (tmp, stack));
5158         }
5159     }
5160   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5161   DONE;
5163   [(set_attr "length" "12")
5164    (set_attr "type" "fpload")])
5166 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5167   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5168         (unsigned_float:SFDF
5169          (zero_extend:DI
5170           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5171    (clobber (match_scratch:DI 2 "=wi"))]
5172   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5173    && <SI_CONVERT_FP>"
5174   "#"
5175   ""
5176   [(pc)]
5177   "
5179   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5180   if (GET_CODE (operands[2]) == SCRATCH)
5181     operands[2] = gen_reg_rtx (DImode);
5182   if (TARGET_VSX_SMALL_INTEGER)
5183     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5184   else
5185     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5186   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5187   DONE;
5189   [(set_attr "length" "8")
5190    (set_attr "type" "fpload")])
5192 ; For each of these conversions, there is a define_expand, a define_insn
5193 ; with a '#' template, and a define_split (with C code).  The idea is
5194 ; to allow constant folding with the template of the define_insn,
5195 ; then to have the insns split later (between sched1 and final).
5197 (define_expand "floatsidf2"
5198   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5199                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5200               (use (match_dup 2))
5201               (use (match_dup 3))
5202               (clobber (match_dup 4))
5203               (clobber (match_dup 5))
5204               (clobber (match_dup 6))])]
5205   "TARGET_HARD_FLOAT 
5206    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5207   "
5209   if (TARGET_E500_DOUBLE)
5210     {
5211       if (!REG_P (operands[1]))
5212         operands[1] = force_reg (SImode, operands[1]);
5213       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5214       DONE;
5215     }
5216   else if (TARGET_LFIWAX && TARGET_FCFID)
5217     {
5218       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5219       DONE;
5220     }
5221   else if (TARGET_FCFID)
5222     {
5223       rtx dreg = operands[1];
5224       if (!REG_P (dreg))
5225         dreg = force_reg (SImode, dreg);
5226       dreg = convert_to_mode (DImode, dreg, false);
5227       emit_insn (gen_floatdidf2 (operands[0], dreg));
5228       DONE;
5229     }
5231   if (!REG_P (operands[1]))
5232     operands[1] = force_reg (SImode, operands[1]);
5233   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5234   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5235   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5236   operands[5] = gen_reg_rtx (DFmode);
5237   operands[6] = gen_reg_rtx (SImode);
5240 (define_insn_and_split "*floatsidf2_internal"
5241   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5242         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5243    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5244    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5245    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5246    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5247    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5248   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5249   "#"
5250   ""
5251   [(pc)]
5252   "
5254   rtx lowword, highword;
5255   gcc_assert (MEM_P (operands[4]));
5256   highword = adjust_address (operands[4], SImode, 0);
5257   lowword = adjust_address (operands[4], SImode, 4);
5258   if (! WORDS_BIG_ENDIAN)
5259     std::swap (lowword, highword);
5261   emit_insn (gen_xorsi3 (operands[6], operands[1],
5262                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5263   emit_move_insn (lowword, operands[6]);
5264   emit_move_insn (highword, operands[2]);
5265   emit_move_insn (operands[5], operands[4]);
5266   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5267   DONE;
5269   [(set_attr "length" "24")
5270    (set_attr "type" "fp")])
5272 ;; If we don't have a direct conversion to single precision, don't enable this
5273 ;; conversion for 32-bit without fast math, because we don't have the insn to
5274 ;; generate the fixup swizzle to avoid double rounding problems.
5275 (define_expand "floatunssisf2"
5276   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5277         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5278   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5279    && (!TARGET_FPRS
5280        || (TARGET_FPRS
5281            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5282                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5283                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5284   "
5286   if (!TARGET_FPRS)
5287     {
5288       if (!REG_P (operands[1]))
5289         operands[1] = force_reg (SImode, operands[1]);
5290     }
5291   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5292     {
5293       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5294       DONE;
5295     }
5296   else
5297     {
5298       rtx dreg = operands[1];
5299       if (!REG_P (dreg))
5300         dreg = force_reg (SImode, dreg);
5301       dreg = convert_to_mode (DImode, dreg, true);
5302       emit_insn (gen_floatdisf2 (operands[0], dreg));
5303       DONE;
5304     }
5307 (define_expand "floatunssidf2"
5308   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5309                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5310               (use (match_dup 2))
5311               (use (match_dup 3))
5312               (clobber (match_dup 4))
5313               (clobber (match_dup 5))])]
5314   "TARGET_HARD_FLOAT
5315    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5316   "
5318   if (TARGET_E500_DOUBLE)
5319     {
5320       if (!REG_P (operands[1]))
5321         operands[1] = force_reg (SImode, operands[1]);
5322       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5323       DONE;
5324     }
5325   else if (TARGET_LFIWZX && TARGET_FCFID)
5326     {
5327       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5328       DONE;
5329     }
5330   else if (TARGET_FCFID)
5331     {
5332       rtx dreg = operands[1];
5333       if (!REG_P (dreg))
5334         dreg = force_reg (SImode, dreg);
5335       dreg = convert_to_mode (DImode, dreg, true);
5336       emit_insn (gen_floatdidf2 (operands[0], dreg));
5337       DONE;
5338     }
5340   if (!REG_P (operands[1]))
5341     operands[1] = force_reg (SImode, operands[1]);
5342   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5343   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5344   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5345   operands[5] = gen_reg_rtx (DFmode);
5348 (define_insn_and_split "*floatunssidf2_internal"
5349   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5350         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5351    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5352    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5353    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5354    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5355   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5356    && !(TARGET_FCFID && TARGET_POWERPC64)"
5357   "#"
5358   ""
5359   [(pc)]
5360   "
5362   rtx lowword, highword;
5363   gcc_assert (MEM_P (operands[4]));
5364   highword = adjust_address (operands[4], SImode, 0);
5365   lowword = adjust_address (operands[4], SImode, 4);
5366   if (! WORDS_BIG_ENDIAN)
5367     std::swap (lowword, highword);
5369   emit_move_insn (lowword, operands[1]);
5370   emit_move_insn (highword, operands[2]);
5371   emit_move_insn (operands[5], operands[4]);
5372   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5373   DONE;
5375   [(set_attr "length" "20")
5376    (set_attr "type" "fp")])
5378 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5379 ;; vector registers.  These insns favor doing the sign/zero extension in
5380 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5381 ;; extension and then a direct move.
5383 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5384   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5385                    (float:FP_ISA3
5386                     (match_operand:QHI 1 "input_operand")))
5387               (clobber (match_scratch:DI 2))
5388               (clobber (match_scratch:DI 3))
5389               (clobber (match_scratch:<QHI:MODE> 4))])]
5390   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5391    && TARGET_VSX_SMALL_INTEGER"
5393   if (MEM_P (operands[1]))
5394     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5397 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5398   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5399         (float:FP_ISA3
5400          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5401    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5402    (clobber (match_scratch:DI 3 "=X,r,X"))
5403    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5404   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5405    && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5406   "#"
5407   "&& reload_completed"
5408   [(const_int 0)]
5410   rtx result = operands[0];
5411   rtx input = operands[1];
5412   rtx di = operands[2];
5414   if (!MEM_P (input))
5415     {
5416       if (altivec_register_operand (input, <QHI:MODE>mode))
5417         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5418       else
5419         {
5420           rtx tmp = operands[3];
5421           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5422           emit_move_insn (di, tmp);
5423         }
5424     }
5425   else
5426     {
5427       rtx tmp = operands[4];
5428       emit_move_insn (tmp, input);
5429       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5430     }
5432   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5433   DONE;
5436 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5437   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5438                    (unsigned_float:FP_ISA3
5439                     (match_operand:QHI 1 "input_operand" "")))
5440               (clobber (match_scratch:DI 2 ""))
5441               (clobber (match_scratch:DI 3 ""))])]
5442   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5443    && TARGET_VSX_SMALL_INTEGER"
5445   if (MEM_P (operands[1]))
5446     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5449 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5450   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5451         (unsigned_float:FP_ISA3
5452          (match_operand:QHI 1 "reg_or_indexed_operand" "wJwK,r,Z")))
5453    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5454    (clobber (match_scratch:DI 3 "=X,r,X"))]
5455   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5456    && TARGET_VSX_SMALL_INTEGER"
5457   "#"
5458   "&& reload_completed"
5459   [(const_int 0)]
5461   rtx result = operands[0];
5462   rtx input = operands[1];
5463   rtx di = operands[2];
5465   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5466     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5467   else
5468     {
5469       rtx tmp = operands[3];
5470       emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5471       emit_move_insn (di, tmp);
5472     }
5474   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5475   DONE;
5478 (define_expand "fix_trunc<mode>si2"
5479   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5480         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5481   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5482   "
5484   if (!<E500_CONVERT>)
5485     {
5486       rtx src = force_reg (<MODE>mode, operands[1]);
5488       if (TARGET_STFIWX)
5489         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5490       else
5491         {
5492           rtx tmp = gen_reg_rtx (DImode);
5493           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5494           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5495                                                       tmp, stack));
5496         }
5497       DONE;
5498     }
5501 ; Like the convert to float patterns, this insn must be split before
5502 ; register allocation so that it can allocate the memory slot if it
5503 ; needed
5504 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5505   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5506         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5507    (clobber (match_scratch:DI 2 "=d"))]
5508   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5509    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5510    && TARGET_STFIWX && can_create_pseudo_p ()"
5511   "#"
5512   ""
5513   [(pc)]
5515   rtx dest = operands[0];
5516   rtx src = operands[1];
5517   rtx tmp = operands[2];
5519   if (GET_CODE (tmp) == SCRATCH)
5520     tmp = gen_reg_rtx (DImode);
5522   emit_insn (gen_fctiwz_<mode> (tmp, src));
5523   if (MEM_P (dest))
5524     {
5525       dest = rs6000_address_for_fpconvert (dest);
5526       emit_insn (gen_stfiwx (dest, tmp));
5527       DONE;
5528     }
5529   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5530     {
5531       dest = gen_lowpart (DImode, dest);
5532       emit_move_insn (dest, tmp);
5533       DONE;
5534     }
5535   else
5536     {
5537       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5538       emit_insn (gen_stfiwx (stack, tmp));
5539       emit_move_insn (dest, stack);
5540       DONE;
5541     }
5543   [(set_attr "length" "12")
5544    (set_attr "type" "fp")])
5546 (define_insn_and_split "fix_trunc<mode>si2_internal"
5547   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5548         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5549    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5550    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5551   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5552   "#"
5553   ""
5554   [(pc)]
5555   "
5557   rtx lowword;
5558   gcc_assert (MEM_P (operands[3]));
5559   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5561   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5562   emit_move_insn (operands[3], operands[2]);
5563   emit_move_insn (operands[0], lowword);
5564   DONE;
5566   [(set_attr "length" "16")
5567    (set_attr "type" "fp")])
5569 (define_expand "fix_trunc<mode>di2"
5570   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5571         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5572   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5573    && TARGET_FCFID"
5574   "")
5576 (define_insn "*fix_trunc<mode>di2_fctidz"
5577   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5578         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5579   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5580     && TARGET_FCFID"
5581   "@
5582    fctidz %0,%1
5583    xscvdpsxds %x0,%x1"
5584   [(set_attr "type" "fp")])
5586 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5587   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5588                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5589               (clobber (match_scratch:DI 2))])]
5590   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5591    && TARGET_VSX_SMALL_INTEGER"
5593   if (MEM_P (operands[0]))
5594     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5597 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5598   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5599         (fix:QHI
5600          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5601    (clobber (match_scratch:DI 2 "=X,wi"))]
5602   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5603    && TARGET_VSX_SMALL_INTEGER"
5604   "#"
5605   "&& reload_completed"
5606   [(const_int 0)]
5608   rtx dest = operands[0];
5609   rtx src = operands[1];
5611   if (vsx_register_operand (dest, <QHI:MODE>mode))
5612     {
5613       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5614       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5615     }
5616   else
5617     {
5618       rtx tmp = operands[2];
5619       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5621       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5622       emit_move_insn (dest, tmp2);
5623     }
5624   DONE;
5627 (define_expand "fixuns_trunc<mode>si2"
5628   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5629         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5630   "TARGET_HARD_FLOAT
5631    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5632        || <E500_CONVERT>)"
5633   "
5635   if (!<E500_CONVERT>)
5636     {
5637       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5638       DONE;
5639     }
5642 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5643   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5644         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5645    (clobber (match_scratch:DI 2 "=d"))]
5646   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5647    && TARGET_STFIWX && can_create_pseudo_p ()"
5648   "#"
5649   ""
5650   [(pc)]
5652   rtx dest = operands[0];
5653   rtx src = operands[1];
5654   rtx tmp = operands[2];
5656   if (GET_CODE (tmp) == SCRATCH)
5657     tmp = gen_reg_rtx (DImode);
5659   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5660   if (MEM_P (dest))
5661     {
5662       dest = rs6000_address_for_fpconvert (dest);
5663       emit_insn (gen_stfiwx (dest, tmp));
5664       DONE;
5665     }
5666   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5667     {
5668       dest = gen_lowpart (DImode, dest);
5669       emit_move_insn (dest, tmp);
5670       DONE;
5671     }
5672   else
5673     {
5674       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5675       emit_insn (gen_stfiwx (stack, tmp));
5676       emit_move_insn (dest, stack);
5677       DONE;
5678     }
5680   [(set_attr "length" "12")
5681    (set_attr "type" "fp")])
5683 (define_expand "fixuns_trunc<mode>di2"
5684   [(set (match_operand:DI 0 "register_operand" "")
5685         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5686   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5687   "")
5689 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5690   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5691         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5692   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5693     && TARGET_FCTIDUZ"
5694   "@
5695    fctiduz %0,%1
5696    xscvdpuxds %x0,%x1"
5697   [(set_attr "type" "fp")])
5699 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5700   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5701                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5702               (clobber (match_scratch:DI 2))])]
5703   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5704    && TARGET_VSX_SMALL_INTEGER"
5706   if (MEM_P (operands[0]))
5707     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5710 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5711   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5712         (unsigned_fix:QHI
5713          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5714    (clobber (match_scratch:DI 2 "=X,wi"))]
5715   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5716    && TARGET_VSX_SMALL_INTEGER"
5717   "#"
5718   "&& reload_completed"
5719   [(const_int 0)]
5721   rtx dest = operands[0];
5722   rtx src = operands[1];
5724   if (vsx_register_operand (dest, <QHI:MODE>mode))
5725     {
5726       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5727       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5728     }
5729   else
5730     {
5731       rtx tmp = operands[2];
5732       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5734       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5735       emit_move_insn (dest, tmp2);
5736     }
5737   DONE;
5739 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5740 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5741 ; because the first makes it clear that operand 0 is not live
5742 ; before the instruction.
5743 (define_insn "fctiwz_<mode>"
5744   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5745         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5746                    UNSPEC_FCTIWZ))]
5747   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5748   "@
5749    fctiwz %0,%1
5750    xscvdpsxws %x0,%x1"
5751   [(set_attr "type" "fp")])
5753 (define_insn "fctiwuz_<mode>"
5754   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5755         (unspec:DI [(unsigned_fix:SI
5756                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5757                    UNSPEC_FCTIWUZ))]
5758   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5759   "@
5760    fctiwuz %0,%1
5761    xscvdpuxws %x0,%x1"
5762   [(set_attr "type" "fp")])
5764 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5765 ;; since the friz instruction does not truncate the value if the floating
5766 ;; point value is < LONG_MIN or > LONG_MAX.
5767 (define_insn "*friz"
5768   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5769         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5770   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5771    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5772   "@
5773    friz %0,%1
5774    xsrdpiz %x0,%x1"
5775   [(set_attr "type" "fp")])
5777 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5778 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5779 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5780 ;; extend it, store it back on the stack from the GPR, load it back into the
5781 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5782 ;; disable using store and load to sign/zero extend the value.
5783 (define_insn_and_split "*round32<mode>2_fprs"
5784   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5785         (float:SFDF
5786          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5787    (clobber (match_scratch:DI 2 "=d"))
5788    (clobber (match_scratch:DI 3 "=d"))]
5789   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5790    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5791    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5792   "#"
5793   ""
5794   [(pc)]
5796   rtx dest = operands[0];
5797   rtx src = operands[1];
5798   rtx tmp1 = operands[2];
5799   rtx tmp2 = operands[3];
5800   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5802   if (GET_CODE (tmp1) == SCRATCH)
5803     tmp1 = gen_reg_rtx (DImode);
5804   if (GET_CODE (tmp2) == SCRATCH)
5805     tmp2 = gen_reg_rtx (DImode);
5807   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5808   emit_insn (gen_stfiwx (stack, tmp1));
5809   emit_insn (gen_lfiwax (tmp2, stack));
5810   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5811   DONE;
5813   [(set_attr "type" "fpload")
5814    (set_attr "length" "16")])
5816 (define_insn_and_split "*roundu32<mode>2_fprs"
5817   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5818         (unsigned_float:SFDF
5819          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5820    (clobber (match_scratch:DI 2 "=d"))
5821    (clobber (match_scratch:DI 3 "=d"))]
5822   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5823    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5824    && can_create_pseudo_p ()"
5825   "#"
5826   ""
5827   [(pc)]
5829   rtx dest = operands[0];
5830   rtx src = operands[1];
5831   rtx tmp1 = operands[2];
5832   rtx tmp2 = operands[3];
5833   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5835   if (GET_CODE (tmp1) == SCRATCH)
5836     tmp1 = gen_reg_rtx (DImode);
5837   if (GET_CODE (tmp2) == SCRATCH)
5838     tmp2 = gen_reg_rtx (DImode);
5840   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5841   emit_insn (gen_stfiwx (stack, tmp1));
5842   emit_insn (gen_lfiwzx (tmp2, stack));
5843   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5844   DONE;
5846   [(set_attr "type" "fpload")
5847    (set_attr "length" "16")])
5849 ;; No VSX equivalent to fctid
5850 (define_insn "lrint<mode>di2"
5851   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5852         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5853                    UNSPEC_FCTID))]
5854   "TARGET_<MODE>_FPR && TARGET_FPRND"
5855   "fctid %0,%1"
5856   [(set_attr "type" "fp")])
5858 (define_insn "btrunc<mode>2"
5859   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5860         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5861                      UNSPEC_FRIZ))]
5862   "TARGET_<MODE>_FPR && TARGET_FPRND"
5863   "@
5864    friz %0,%1
5865    xsrdpiz %x0,%x1"
5866   [(set_attr "type" "fp")
5867    (set_attr "fp_type" "fp_addsub_<Fs>")])
5869 (define_insn "ceil<mode>2"
5870   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5871         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5872                      UNSPEC_FRIP))]
5873   "TARGET_<MODE>_FPR && TARGET_FPRND"
5874   "@
5875    frip %0,%1
5876    xsrdpip %x0,%x1"
5877   [(set_attr "type" "fp")
5878    (set_attr "fp_type" "fp_addsub_<Fs>")])
5880 (define_insn "floor<mode>2"
5881   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5882         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5883                      UNSPEC_FRIM))]
5884   "TARGET_<MODE>_FPR && TARGET_FPRND"
5885   "@
5886    frim %0,%1
5887    xsrdpim %x0,%x1"
5888   [(set_attr "type" "fp")
5889    (set_attr "fp_type" "fp_addsub_<Fs>")])
5891 ;; No VSX equivalent to frin
5892 (define_insn "round<mode>2"
5893   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5894         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5895                      UNSPEC_FRIN))]
5896   "TARGET_<MODE>_FPR && TARGET_FPRND"
5897   "frin %0,%1"
5898   [(set_attr "type" "fp")
5899    (set_attr "fp_type" "fp_addsub_<Fs>")])
5901 (define_insn "*xsrdpi<mode>2"
5902   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5903         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5904                      UNSPEC_XSRDPI))]
5905   "TARGET_<MODE>_FPR && TARGET_VSX"
5906   "xsrdpi %x0,%x1"
5907   [(set_attr "type" "fp")
5908    (set_attr "fp_type" "fp_addsub_<Fs>")])
5910 (define_expand "lround<mode>di2"
5911   [(set (match_dup 2)
5912         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5913                      UNSPEC_XSRDPI))
5914    (set (match_operand:DI 0 "gpc_reg_operand" "")
5915         (unspec:DI [(match_dup 2)]
5916                    UNSPEC_FCTID))]
5917   "TARGET_<MODE>_FPR && TARGET_VSX"
5919   operands[2] = gen_reg_rtx (<MODE>mode);
5922 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5923 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5924 ; is only generated for Power8 or later.
5925 (define_insn "stfiwx"
5926   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5927         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5928                    UNSPEC_STFIWX))]
5929   "TARGET_PPC_GFXOPT"
5930   "@
5931    stfiwx %1,%y0
5932    stxsiwx %x1,%y0"
5933   [(set_attr "type" "fpstore")])
5935 ;; If we don't have a direct conversion to single precision, don't enable this
5936 ;; conversion for 32-bit without fast math, because we don't have the insn to
5937 ;; generate the fixup swizzle to avoid double rounding problems.
5938 (define_expand "floatsisf2"
5939   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5940         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5941   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5942    && (!TARGET_FPRS
5943        || (TARGET_FPRS
5944            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5945                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5946                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5947   "
5949   if (!TARGET_FPRS)
5950     {
5951       if (!REG_P (operands[1]))
5952         operands[1] = force_reg (SImode, operands[1]);
5953     }
5954   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5955     {
5956       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5957       DONE;
5958     }
5959   else if (TARGET_FCFID && TARGET_LFIWAX)
5960     {
5961       rtx dfreg = gen_reg_rtx (DFmode);
5962       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5963       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5964       DONE;
5965     }
5966   else
5967     {
5968       rtx dreg = operands[1];
5969       if (!REG_P (dreg))
5970         dreg = force_reg (SImode, dreg);
5971       dreg = convert_to_mode (DImode, dreg, false);
5972       emit_insn (gen_floatdisf2 (operands[0], dreg));
5973       DONE;
5974     }
5977 (define_expand "floatdidf2"
5978   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5979         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5980   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5981   "")
5983 (define_insn "*floatdidf2_fpr"
5984   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5985         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5986   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5987   "@
5988    fcfid %0,%1
5989    xscvsxddp %x0,%x1"
5990   [(set_attr "type" "fp")])
5992 ; Allow the combiner to merge source memory operands to the conversion so that
5993 ; the optimizer/register allocator doesn't try to load the value too early in a
5994 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5995 ; hit.  We will split after reload to avoid the trip through the GPRs
5997 (define_insn_and_split "*floatdidf2_mem"
5998   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5999         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6000    (clobber (match_scratch:DI 2 "=d,wi"))]
6001   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6002   "#"
6003   "&& reload_completed"
6004   [(set (match_dup 2) (match_dup 1))
6005    (set (match_dup 0) (float:DF (match_dup 2)))]
6006   ""
6007   [(set_attr "length" "8")
6008    (set_attr "type" "fpload")])
6010 (define_expand "floatunsdidf2"
6011   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6012         (unsigned_float:DF
6013          (match_operand:DI 1 "gpc_reg_operand" "")))]
6014   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6015   "")
6017 (define_insn "*floatunsdidf2_fcfidu"
6018   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6019         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6020   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6021   "@
6022    fcfidu %0,%1
6023    xscvuxddp %x0,%x1"
6024   [(set_attr "type" "fp")
6025    (set_attr "length" "4")])
6027 (define_insn_and_split "*floatunsdidf2_mem"
6028   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6029         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6030    (clobber (match_scratch:DI 2 "=d,wi"))]
6031   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6032   "#"
6033   "&& reload_completed"
6034   [(set (match_dup 2) (match_dup 1))
6035    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6036   ""
6037   [(set_attr "length" "8")
6038    (set_attr "type" "fpload")])
6040 (define_expand "floatdisf2"
6041   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6042         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6043   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6044    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6045   "
6047   if (!TARGET_FCFIDS)
6048     {
6049       rtx val = operands[1];
6050       if (!flag_unsafe_math_optimizations)
6051         {
6052           rtx label = gen_label_rtx ();
6053           val = gen_reg_rtx (DImode);
6054           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6055           emit_label (label);
6056         }
6057       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6058       DONE;
6059     }
6062 (define_insn "floatdisf2_fcfids"
6063   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6064         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6065   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6066    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6067   "@
6068    fcfids %0,%1
6069    xscvsxdsp %x0,%x1"
6070   [(set_attr "type" "fp")])
6072 (define_insn_and_split "*floatdisf2_mem"
6073   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6074         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6075    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6076   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6077    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6078   "#"
6079   "&& reload_completed"
6080   [(pc)]
6081   "
6083   emit_move_insn (operands[2], operands[1]);
6084   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6085   DONE;
6087   [(set_attr "length" "8")])
6089 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6090 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6091 ;; from double rounding.
6092 ;; Instead of creating a new cpu type for two FP operations, just use fp
6093 (define_insn_and_split "floatdisf2_internal1"
6094   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6095         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6096    (clobber (match_scratch:DF 2 "=d"))]
6097   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6098    && !TARGET_FCFIDS"
6099   "#"
6100   "&& reload_completed"
6101   [(set (match_dup 2)
6102         (float:DF (match_dup 1)))
6103    (set (match_dup 0)
6104         (float_truncate:SF (match_dup 2)))]
6105   ""
6106   [(set_attr "length" "8")
6107    (set_attr "type" "fp")])
6109 ;; Twiddles bits to avoid double rounding.
6110 ;; Bits that might be truncated when converting to DFmode are replaced
6111 ;; by a bit that won't be lost at that stage, but is below the SFmode
6112 ;; rounding position.
6113 (define_expand "floatdisf2_internal2"
6114   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6115                                               (const_int 53)))
6116               (clobber (reg:DI CA_REGNO))])
6117    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6118                                            (const_int 2047)))
6119    (set (match_dup 3) (plus:DI (match_dup 3)
6120                                (const_int 1)))
6121    (set (match_dup 0) (plus:DI (match_dup 0)
6122                                (const_int 2047)))
6123    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6124                                      (const_int 2)))
6125    (set (match_dup 0) (ior:DI (match_dup 0)
6126                               (match_dup 1)))
6127    (set (match_dup 0) (and:DI (match_dup 0)
6128                               (const_int -2048)))
6129    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6130                            (label_ref (match_operand:DI 2 "" ""))
6131                            (pc)))
6132    (set (match_dup 0) (match_dup 1))]
6133   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6134    && !TARGET_FCFIDS"
6135   "
6137   operands[3] = gen_reg_rtx (DImode);
6138   operands[4] = gen_reg_rtx (CCUNSmode);
6141 (define_expand "floatunsdisf2"
6142   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6143         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6144   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6145    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6146   "")
6148 (define_insn "floatunsdisf2_fcfidus"
6149   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6150         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6151   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6152    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6153   "@
6154    fcfidus %0,%1
6155    xscvuxdsp %x0,%x1"
6156   [(set_attr "type" "fp")])
6158 (define_insn_and_split "*floatunsdisf2_mem"
6159   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6160         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6161    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6162   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6163    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6164   "#"
6165   "&& reload_completed"
6166   [(pc)]
6167   "
6169   emit_move_insn (operands[2], operands[1]);
6170   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6171   DONE;
6173   [(set_attr "length" "8")
6174    (set_attr "type" "fpload")])
6176 ;; Define the TImode operations that can be done in a small number
6177 ;; of instructions.  The & constraints are to prevent the register
6178 ;; allocator from allocating registers that overlap with the inputs
6179 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6180 ;; also allow for the output being the same as one of the inputs.
6182 (define_expand "addti3"
6183   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6184         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6185                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6186   "TARGET_64BIT"
6188   rtx lo0 = gen_lowpart (DImode, operands[0]);
6189   rtx lo1 = gen_lowpart (DImode, operands[1]);
6190   rtx lo2 = gen_lowpart (DImode, operands[2]);
6191   rtx hi0 = gen_highpart (DImode, operands[0]);
6192   rtx hi1 = gen_highpart (DImode, operands[1]);
6193   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6195   if (!reg_or_short_operand (lo2, DImode))
6196     lo2 = force_reg (DImode, lo2);
6197   if (!adde_operand (hi2, DImode))
6198     hi2 = force_reg (DImode, hi2);
6200   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6201   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6202   DONE;
6205 (define_expand "subti3"
6206   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6207         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6208                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6209   "TARGET_64BIT"
6211   rtx lo0 = gen_lowpart (DImode, operands[0]);
6212   rtx lo1 = gen_lowpart (DImode, operands[1]);
6213   rtx lo2 = gen_lowpart (DImode, operands[2]);
6214   rtx hi0 = gen_highpart (DImode, operands[0]);
6215   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6216   rtx hi2 = gen_highpart (DImode, operands[2]);
6218   if (!reg_or_short_operand (lo1, DImode))
6219     lo1 = force_reg (DImode, lo1);
6220   if (!adde_operand (hi1, DImode))
6221     hi1 = force_reg (DImode, hi1);
6223   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6224   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6225   DONE;
6228 ;; 128-bit logical operations expanders
6230 (define_expand "and<mode>3"
6231   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6232         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6233                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6234   ""
6235   "")
6237 (define_expand "ior<mode>3"
6238   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6239         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6240                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6241   ""
6242   "")
6244 (define_expand "xor<mode>3"
6245   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6246         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6247                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6248   ""
6249   "")
6251 (define_expand "one_cmpl<mode>2"
6252   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6253         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6254   ""
6255   "")
6257 (define_expand "nor<mode>3"
6258   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6259         (and:BOOL_128
6260          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6261          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6262   ""
6263   "")
6265 (define_expand "andc<mode>3"
6266   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6267         (and:BOOL_128
6268          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6269          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6270   ""
6271   "")
6273 ;; Power8 vector logical instructions.
6274 (define_expand "eqv<mode>3"
6275   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6276         (not:BOOL_128
6277          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6278                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6279   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6280   "")
6282 ;; Rewrite nand into canonical form
6283 (define_expand "nand<mode>3"
6284   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6285         (ior:BOOL_128
6286          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6287          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6288   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6289   "")
6291 ;; The canonical form is to have the negated element first, so we need to
6292 ;; reverse arguments.
6293 (define_expand "orc<mode>3"
6294   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6295         (ior:BOOL_128
6296          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6297          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6298   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6299   "")
6301 ;; 128-bit logical operations insns and split operations
6302 (define_insn_and_split "*and<mode>3_internal"
6303   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6304         (and:BOOL_128
6305          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6306          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6307   ""
6309   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6310     return "xxland %x0,%x1,%x2";
6312   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6313     return "vand %0,%1,%2";
6315   return "#";
6317   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6318   [(const_int 0)]
6320   rs6000_split_logical (operands, AND, false, false, false);
6321   DONE;
6323   [(set (attr "type")
6324       (if_then_else
6325         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6326         (const_string "veclogical")
6327         (const_string "integer")))
6328    (set (attr "length")
6329       (if_then_else
6330         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6331         (const_string "4")
6332         (if_then_else
6333          (match_test "TARGET_POWERPC64")
6334          (const_string "8")
6335          (const_string "16"))))])
6337 ;; 128-bit IOR/XOR
6338 (define_insn_and_split "*bool<mode>3_internal"
6339   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6340         (match_operator:BOOL_128 3 "boolean_or_operator"
6341          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6342           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6343   ""
6345   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6346     return "xxl%q3 %x0,%x1,%x2";
6348   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6349     return "v%q3 %0,%1,%2";
6351   return "#";
6353   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6354   [(const_int 0)]
6356   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6357   DONE;
6359   [(set (attr "type")
6360       (if_then_else
6361         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6362         (const_string "veclogical")
6363         (const_string "integer")))
6364    (set (attr "length")
6365       (if_then_else
6366         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6367         (const_string "4")
6368         (if_then_else
6369          (match_test "TARGET_POWERPC64")
6370          (const_string "8")
6371          (const_string "16"))))])
6373 ;; 128-bit ANDC/ORC
6374 (define_insn_and_split "*boolc<mode>3_internal1"
6375   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6376         (match_operator:BOOL_128 3 "boolean_operator"
6377          [(not:BOOL_128
6378            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6379           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6380   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6382   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6383     return "xxl%q3 %x0,%x1,%x2";
6385   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6386     return "v%q3 %0,%1,%2";
6388   return "#";
6390   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6391    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6392   [(const_int 0)]
6394   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6395   DONE;
6397   [(set (attr "type")
6398       (if_then_else
6399         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6400         (const_string "veclogical")
6401         (const_string "integer")))
6402    (set (attr "length")
6403       (if_then_else
6404         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6405         (const_string "4")
6406         (if_then_else
6407          (match_test "TARGET_POWERPC64")
6408          (const_string "8")
6409          (const_string "16"))))])
6411 (define_insn_and_split "*boolc<mode>3_internal2"
6412   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6413         (match_operator:TI2 3 "boolean_operator"
6414          [(not:TI2
6415            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6416           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6417   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6418   "#"
6419   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6420   [(const_int 0)]
6422   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6423   DONE;
6425   [(set_attr "type" "integer")
6426    (set (attr "length")
6427         (if_then_else
6428          (match_test "TARGET_POWERPC64")
6429          (const_string "8")
6430          (const_string "16")))])
6432 ;; 128-bit NAND/NOR
6433 (define_insn_and_split "*boolcc<mode>3_internal1"
6434   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6435         (match_operator:BOOL_128 3 "boolean_operator"
6436          [(not:BOOL_128
6437            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6438           (not:BOOL_128
6439            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6440   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6442   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6443     return "xxl%q3 %x0,%x1,%x2";
6445   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6446     return "v%q3 %0,%1,%2";
6448   return "#";
6450   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6451    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6452   [(const_int 0)]
6454   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6455   DONE;
6457   [(set (attr "type")
6458       (if_then_else
6459         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6460         (const_string "veclogical")
6461         (const_string "integer")))
6462    (set (attr "length")
6463       (if_then_else
6464         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6465         (const_string "4")
6466         (if_then_else
6467          (match_test "TARGET_POWERPC64")
6468          (const_string "8")
6469          (const_string "16"))))])
6471 (define_insn_and_split "*boolcc<mode>3_internal2"
6472   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6473         (match_operator:TI2 3 "boolean_operator"
6474          [(not:TI2
6475            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6476           (not:TI2
6477            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6478   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6479   "#"
6480   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6481   [(const_int 0)]
6483   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6484   DONE;
6486   [(set_attr "type" "integer")
6487    (set (attr "length")
6488         (if_then_else
6489          (match_test "TARGET_POWERPC64")
6490          (const_string "8")
6491          (const_string "16")))])
6494 ;; 128-bit EQV
6495 (define_insn_and_split "*eqv<mode>3_internal1"
6496   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6497         (not:BOOL_128
6498          (xor:BOOL_128
6499           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6500           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6501   "TARGET_P8_VECTOR"
6503   if (vsx_register_operand (operands[0], <MODE>mode))
6504     return "xxleqv %x0,%x1,%x2";
6506   return "#";
6508   "TARGET_P8_VECTOR && reload_completed
6509    && int_reg_operand (operands[0], <MODE>mode)"
6510   [(const_int 0)]
6512   rs6000_split_logical (operands, XOR, true, false, false);
6513   DONE;
6515   [(set (attr "type")
6516       (if_then_else
6517         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6518         (const_string "veclogical")
6519         (const_string "integer")))
6520    (set (attr "length")
6521       (if_then_else
6522         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6523         (const_string "4")
6524         (if_then_else
6525          (match_test "TARGET_POWERPC64")
6526          (const_string "8")
6527          (const_string "16"))))])
6529 (define_insn_and_split "*eqv<mode>3_internal2"
6530   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6531         (not:TI2
6532          (xor:TI2
6533           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6534           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6535   "!TARGET_P8_VECTOR"
6536   "#"
6537   "reload_completed && !TARGET_P8_VECTOR"
6538   [(const_int 0)]
6540   rs6000_split_logical (operands, XOR, true, false, false);
6541   DONE;
6543   [(set_attr "type" "integer")
6544    (set (attr "length")
6545         (if_then_else
6546          (match_test "TARGET_POWERPC64")
6547          (const_string "8")
6548          (const_string "16")))])
6550 ;; 128-bit one's complement
6551 (define_insn_and_split "*one_cmpl<mode>3_internal"
6552   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6553         (not:BOOL_128
6554           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6555   ""
6557   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6558     return "xxlnor %x0,%x1,%x1";
6560   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6561     return "vnor %0,%1,%1";
6563   return "#";
6565   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6566   [(const_int 0)]
6568   rs6000_split_logical (operands, NOT, false, false, false);
6569   DONE;
6571   [(set (attr "type")
6572       (if_then_else
6573         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6574         (const_string "veclogical")
6575         (const_string "integer")))
6576    (set (attr "length")
6577       (if_then_else
6578         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6579         (const_string "4")
6580         (if_then_else
6581          (match_test "TARGET_POWERPC64")
6582          (const_string "8")
6583          (const_string "16"))))])
6586 ;; Now define ways of moving data around.
6588 ;; Set up a register with a value from the GOT table
6590 (define_expand "movsi_got"
6591   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6592         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6593                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6594   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6595   "
6597   if (GET_CODE (operands[1]) == CONST)
6598     {
6599       rtx offset = const0_rtx;
6600       HOST_WIDE_INT value;
6602       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6603       value = INTVAL (offset);
6604       if (value != 0)
6605         {
6606           rtx tmp = (!can_create_pseudo_p ()
6607                      ? operands[0]
6608                      : gen_reg_rtx (Pmode));
6609           emit_insn (gen_movsi_got (tmp, operands[1]));
6610           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6611           DONE;
6612         }
6613     }
6615   operands[2] = rs6000_got_register (operands[1]);
6618 (define_insn "*movsi_got_internal"
6619   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6620         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6621                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6622                    UNSPEC_MOVSI_GOT))]
6623   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6624   "lwz %0,%a1@got(%2)"
6625   [(set_attr "type" "load")])
6627 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6628 ;; didn't get allocated to a hard register.
6629 (define_split
6630   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6631         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6632                     (match_operand:SI 2 "memory_operand" "")]
6633                    UNSPEC_MOVSI_GOT))]
6634   "DEFAULT_ABI == ABI_V4
6635     && flag_pic == 1
6636     && (reload_in_progress || reload_completed)"
6637   [(set (match_dup 0) (match_dup 2))
6638    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6639                                  UNSPEC_MOVSI_GOT))]
6640   "")
6642 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6643 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6644 ;; and this is even supposed to be faster, but it is simpler not to get
6645 ;; integers in the TOC.
6646 (define_insn "movsi_low"
6647   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6648         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6649                            (match_operand 2 "" ""))))]
6650   "TARGET_MACHO && ! TARGET_64BIT"
6651   "lwz %0,lo16(%2)(%1)"
6652   [(set_attr "type" "load")
6653    (set_attr "length" "4")])
6655 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6656 ;;              STW          STFIWX       STXSIWX      LI           LIS
6657 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6658 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6659 ;;              MF%1         MT%0         MT%0         NOP
6660 (define_insn "*movsi_internal1"
6661   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6662                 "=r,         r,           r,           ?*wI,        ?*wH,
6663                  m,          ?Z,          ?Z,          r,           r,
6664                  r,          ?*wIwH,      ?*wJwK,      ?*wK,        ?*wJwK,
6665                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6666                  r,          *c*l,        *h,          *h")
6668         (match_operand:SI 1 "input_operand"
6669                 "r,          U,           m,           Z,           Z,
6670                  r,          wI,          wH,          I,           L,
6671                  n,          wIwH,        O,           wM,          wB,
6672                  O,          wM,          wS,          r,           wIwH,
6673                  *h,         r,           r,           0"))]
6675   "!TARGET_SINGLE_FPU &&
6676    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6677   "@
6678    mr %0,%1
6679    la %0,%a1
6680    lwz%U1%X1 %0,%1
6681    lfiwzx %0,%y1
6682    lxsiwzx %x0,%y1
6683    stw%U0%X0 %1,%0
6684    stfiwx %1,%y0
6685    stxsiwx %x1,%y0
6686    li %0,%1
6687    lis %0,%v1
6688    #
6689    xxlor %x0,%x1,%x1
6690    xxspltib %x0,0
6691    xxspltib %x0,255
6692    vspltisw %0,%1
6693    xxlxor %x0,%x0,%x0
6694    xxlorc %x0,%x0,%x0
6695    #
6696    mtvsrwz %x0,%1
6697    mfvsrwz %0,%x1
6698    mf%1 %0
6699    mt%0 %1
6700    mt%0 %1
6701    nop"
6702   [(set_attr "type"
6703                 "*,          *,           load,        fpload,      fpload,
6704                  store,      fpstore,     fpstore,     *,           *,
6705                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6706                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6707                  *,           *,           *,           *")
6709    (set_attr "length"
6710                 "4,          4,           4,           4,           4,
6711                  4,          4,           4,           4,           4,
6712                  8,          4,           4,           4,           4,
6713                  4,          4,           8,           4,           4,
6714                  4,          4,           4,           4")])
6716 (define_insn "*movsi_internal1_single"
6717   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6718         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6719   "TARGET_SINGLE_FPU &&
6720    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6721   "@
6722    mr %0,%1
6723    la %0,%a1
6724    lwz%U1%X1 %0,%1
6725    stw%U0%X0 %1,%0
6726    li %0,%1
6727    lis %0,%v1
6728    #
6729    mf%1 %0
6730    mt%0 %1
6731    mt%0 %1
6732    nop
6733    stfs%U0%X0 %1,%0
6734    lfs%U1%X1 %0,%1"
6735   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6736    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6738 ;; Split a load of a large constant into the appropriate two-insn
6739 ;; sequence.
6741 (define_split
6742   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6743         (match_operand:SI 1 "const_int_operand" ""))]
6744   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6745    && (INTVAL (operands[1]) & 0xffff) != 0"
6746   [(set (match_dup 0)
6747         (match_dup 2))
6748    (set (match_dup 0)
6749         (ior:SI (match_dup 0)
6750                 (match_dup 3)))]
6751   "
6753   if (rs6000_emit_set_const (operands[0], operands[1]))
6754     DONE;
6755   else
6756     FAIL;
6759 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6760 (define_split
6761   [(set (match_operand:DI 0 "altivec_register_operand")
6762         (match_operand:DI 1 "xxspltib_constant_split"))]
6763   "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6764   [(const_int 0)]
6766   rtx op0 = operands[0];
6767   rtx op1 = operands[1];
6768   int r = REGNO (op0);
6769   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6771   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6772   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6773   DONE;
6776 (define_insn "*mov<mode>_internal2"
6777   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6778         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6779                     (const_int 0)))
6780    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6781   ""
6782   "@
6783    cmp<wd>i %2,%0,0
6784    mr. %0,%1
6785    #"
6786   [(set_attr "type" "cmp,logical,cmp")
6787    (set_attr "dot" "yes")
6788    (set_attr "length" "4,4,8")])
6790 (define_split
6791   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6792         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6793                     (const_int 0)))
6794    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6795   "reload_completed"
6796   [(set (match_dup 0) (match_dup 1))
6797    (set (match_dup 2)
6798         (compare:CC (match_dup 0)
6799                     (const_int 0)))]
6800   "")
6802 (define_expand "mov<mode>"
6803   [(set (match_operand:INT 0 "general_operand" "")
6804         (match_operand:INT 1 "any_operand" ""))]
6805   ""
6806   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6808 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
6809 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
6810 ;;              MTVSRWZ     MF%1       MT%1       NOP
6811 (define_insn "*mov<mode>_internal"
6812   [(set (match_operand:QHI 0 "nonimmediate_operand"
6813                 "=r,        r,         ?*wJwK,    m,         Z,         r,
6814                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
6815                  ?*wJwK,    r,         *c*l,      *h")
6817         (match_operand:QHI 1 "input_operand"
6818                 "r,         m,         Z,         r,         wJwK,      i,
6819                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
6820                  r,         *h,        r,         0"))]
6822   "gpc_reg_operand (operands[0], <MODE>mode)
6823    || gpc_reg_operand (operands[1], <MODE>mode)"
6824   "@
6825    mr %0,%1
6826    l<wd>z%U1%X1 %0,%1
6827    lxsi<wd>zx %x0,%y1
6828    st<wd>%U0%X0 %1,%0
6829    stxsi<wd>x %x1,%y0
6830    li %0,%1
6831    xxlor %x0,%x1,%x1
6832    xxspltib %x0,0
6833    xxspltib %x0,255
6834    vspltis<wd> %0,%1
6835    #
6836    mfvsrwz %0,%x1
6837    mtvsrwz %x0,%1
6838    mf%1 %0
6839    mt%0 %1
6840    nop"
6841   [(set_attr "type"
6842                 "*,         load,      fpload,    store,     fpstore,   *,
6843                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
6844                  mffgpr,    mfjmpr,    mtjmpr,    *")
6846    (set_attr "length"
6847                 "4,         4,         4,         4,         4,         4,
6848                  4,         4,         4,         4,         8,         4,
6849                  4,         4,         4,         4")])
6852 ;; Here is how to move condition codes around.  When we store CC data in
6853 ;; an integer register or memory, we store just the high-order 4 bits.
6854 ;; This lets us not shift in the most common case of CR0.
6855 (define_expand "movcc"
6856   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6857         (match_operand:CC 1 "nonimmediate_operand" ""))]
6858   ""
6859   "")
6861 (define_insn "*movcc_internal1"
6862   [(set (match_operand:CC 0 "nonimmediate_operand"
6863                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
6864         (match_operand:CC 1 "general_operand"
6865                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
6866   "register_operand (operands[0], CCmode)
6867    || register_operand (operands[1], CCmode)"
6868   "@
6869    mcrf %0,%1
6870    mtcrf 128,%1
6871    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6872    crxor %0,%0,%0
6873    mfcr %0%Q1
6874    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6875    mr %0,%1
6876    li %0,%1
6877    mf%1 %0
6878    mt%0 %1
6879    lwz%U1%X1 %0,%1
6880    stw%U0%X0 %1,%0"
6881   [(set (attr "type")
6882      (cond [(eq_attr "alternative" "0,3")
6883                 (const_string "cr_logical")
6884             (eq_attr "alternative" "1,2")
6885                 (const_string "mtcr")
6886             (eq_attr "alternative" "6,7")
6887                 (const_string "integer")
6888             (eq_attr "alternative" "8")
6889                 (const_string "mfjmpr")
6890             (eq_attr "alternative" "9")
6891                 (const_string "mtjmpr")
6892             (eq_attr "alternative" "10")
6893                 (const_string "load")
6894             (eq_attr "alternative" "11")
6895                 (const_string "store")
6896             (match_test "TARGET_MFCRF")
6897                 (const_string "mfcrf")
6898            ]
6899         (const_string "mfcr")))
6900    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6902 ;; For floating-point, we normally deal with the floating-point registers
6903 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6904 ;; can produce floating-point values in fixed-point registers.  Unless the
6905 ;; value is a simple constant or already in memory, we deal with this by
6906 ;; allocating memory and copying the value explicitly via that memory location.
6908 ;; Move 32-bit binary/decimal floating point
6909 (define_expand "mov<mode>"
6910   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6911         (match_operand:FMOVE32 1 "any_operand" ""))]
6912   "<fmove_ok>"
6913   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6915 (define_split
6916   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6917         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6918   "reload_completed
6919    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6920        || (GET_CODE (operands[0]) == SUBREG
6921            && GET_CODE (SUBREG_REG (operands[0])) == REG
6922            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6923   [(set (match_dup 2) (match_dup 3))]
6924   "
6926   long l;
6928   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6930   if (! TARGET_POWERPC64)
6931     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6932   else
6933     operands[2] = gen_lowpart (SImode, operands[0]);
6935   operands[3] = gen_int_mode (l, SImode);
6938 (define_insn "mov<mode>_hardfloat"
6939   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
6940          "=!r,       <f32_lr>,  <f32_lr2>, <f32_av>,  m,         <f32_sm>,
6941           <f32_sm2>, Z,         <f32_vsx>, !r,        ?<f32_dm>, ?r,
6942           f,         <f32_vsx>, !r,        *c*l,      !r,        *h")
6943         (match_operand:FMOVE32 1 "input_operand"
6944          "m,         <f32_lm>,  <f32_lm2>, Z,         r,         <f32_sr>,
6945           <f32_sr2>, <f32_av>,  <zero_fp>, <zero_fp>, r,         <f32_dm>,
6946           f,         <f32_vsx>, r,         r,         *h,        0"))]
6947   "(gpc_reg_operand (operands[0], <MODE>mode)
6948    || gpc_reg_operand (operands[1], <MODE>mode))
6949    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6950   "@
6951    lwz%U1%X1 %0,%1
6952    <f32_li>
6953    <f32_li2>
6954    <f32_lv>
6955    stw%U0%X0 %1,%0
6956    <f32_si>
6957    <f32_si2>
6958    <f32_sv>
6959    xxlxor %x0,%x0,%x0
6960    li %0,0
6961    mtvsrwz %x0,%1
6962    mfvsrwz %0,%x1
6963    fmr %0,%1
6964    xscpsgndp %x0,%x1,%x1
6965    mr %0,%1
6966    mt%0 %1
6967    mf%1 %0
6968    nop"
6969   [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
6971 (define_insn "*mov<mode>_softfloat"
6972   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6973         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6974   "(gpc_reg_operand (operands[0], <MODE>mode)
6975    || gpc_reg_operand (operands[1], <MODE>mode))
6976    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6977   "@
6978    mr %0,%1
6979    mt%0 %1
6980    mf%1 %0
6981    lwz%U1%X1 %0,%1
6982    stw%U0%X0 %1,%0
6983    li %0,%1
6984    lis %0,%v1
6985    #
6986    #
6987    nop"
6988   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6989    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6992 ;; Move 64-bit binary/decimal floating point
6993 (define_expand "mov<mode>"
6994   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6995         (match_operand:FMOVE64 1 "any_operand" ""))]
6996   ""
6997   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6999 (define_split
7000   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7001         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7002   "! TARGET_POWERPC64 && reload_completed
7003    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7004        || (GET_CODE (operands[0]) == SUBREG
7005            && GET_CODE (SUBREG_REG (operands[0])) == REG
7006            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7007   [(set (match_dup 2) (match_dup 4))
7008    (set (match_dup 3) (match_dup 1))]
7009   "
7011   int endian = (WORDS_BIG_ENDIAN == 0);
7012   HOST_WIDE_INT value = INTVAL (operands[1]);
7014   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7015   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7016   operands[4] = GEN_INT (value >> 32);
7017   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7020 (define_split
7021   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7022         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7023   "! TARGET_POWERPC64 && reload_completed
7024    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7025        || (GET_CODE (operands[0]) == SUBREG
7026            && GET_CODE (SUBREG_REG (operands[0])) == REG
7027            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7028   [(set (match_dup 2) (match_dup 4))
7029    (set (match_dup 3) (match_dup 5))]
7030   "
7032   int endian = (WORDS_BIG_ENDIAN == 0);
7033   long l[2];
7035   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7037   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7038   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7039   operands[4] = gen_int_mode (l[endian], SImode);
7040   operands[5] = gen_int_mode (l[1 - endian], SImode);
7043 (define_split
7044   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7045         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7046   "TARGET_POWERPC64 && reload_completed
7047    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7048        || (GET_CODE (operands[0]) == SUBREG
7049            && GET_CODE (SUBREG_REG (operands[0])) == REG
7050            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7051   [(set (match_dup 2) (match_dup 3))]
7052   "
7054   int endian = (WORDS_BIG_ENDIAN == 0);
7055   long l[2];
7056   HOST_WIDE_INT val;
7058   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7060   operands[2] = gen_lowpart (DImode, operands[0]);
7061   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7062   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7063          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7065   operands[3] = gen_int_mode (val, DImode);
7068 ;; Don't have reload use general registers to load a constant.  It is
7069 ;; less efficient than loading the constant into an FP register, since
7070 ;; it will probably be used there.
7072 ;; The move constraints are ordered to prefer floating point registers before
7073 ;; general purpose registers to avoid doing a store and a load to get the value
7074 ;; into a floating point register when it is needed for a floating point
7075 ;; operation.  Prefer traditional floating point registers over VSX registers,
7076 ;; since the D-form version of the memory instructions does not need a GPR for
7077 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7078 ;; registers.
7080 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7081 ;; except for 0.0 which can be created on VSX with an xor instruction.
7083 (define_insn "*mov<mode>_hardfloat32"
7084   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7085         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7086   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7087    && (gpc_reg_operand (operands[0], <MODE>mode)
7088        || gpc_reg_operand (operands[1], <MODE>mode))"
7089   "@
7090    stfd%U0%X0 %1,%0
7091    lfd%U1%X1 %0,%1
7092    fmr %0,%1
7093    lxsd%U1x %x0,%y1
7094    stxsd%U0x %x1,%y0
7095    lxsd %0,%1
7096    stxsd %1,%0
7097    xxlor %x0,%x1,%x1
7098    xxlxor %x0,%x0,%x0
7099    #
7100    #
7101    #
7102    #"
7103   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7104    (set_attr "size" "64")
7105    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7107 (define_insn "*mov<mode>_softfloat32"
7108   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7109         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7110   "! TARGET_POWERPC64 
7111    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
7112        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7113        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7114    && (gpc_reg_operand (operands[0], <MODE>mode)
7115        || gpc_reg_operand (operands[1], <MODE>mode))"
7116   "#"
7117   [(set_attr "type" "store,load,two,*,*,*")
7118    (set_attr "length" "8,8,8,8,12,16")])
7120 ; ld/std require word-aligned displacements -> 'Y' constraint.
7121 ; List Y->r and r->Y before r->r for reload.
7122 (define_insn "*mov<mode>_hardfloat64"
7123   [(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>")
7124         (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"))]
7125   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7126    && (gpc_reg_operand (operands[0], <MODE>mode)
7127        || gpc_reg_operand (operands[1], <MODE>mode))"
7128   "@
7129    stfd%U0%X0 %1,%0
7130    lfd%U1%X1 %0,%1
7131    fmr %0,%1
7132    lxsd %0,%1
7133    stxsd %1,%0
7134    lxsd%U1x %x0,%y1
7135    stxsd%U0x %x1,%y0
7136    xxlor %x0,%x1,%x1
7137    xxlxor %x0,%x0,%x0
7138    li %0,0
7139    std%U0%X0 %1,%0
7140    ld%U1%X1 %0,%1
7141    mr %0,%1
7142    mt%0 %1
7143    mf%1 %0
7144    nop
7145    mftgpr %0,%1
7146    mffgpr %0,%1
7147    mfvsrd %0,%x1
7148    mtvsrd %x0,%1"
7149   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7150    (set_attr "size" "64")
7151    (set_attr "length" "4")])
7153 (define_insn "*mov<mode>_softfloat64"
7154   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7155         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7156   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7157    && (gpc_reg_operand (operands[0], <MODE>mode)
7158        || gpc_reg_operand (operands[1], <MODE>mode))"
7159   "@
7160    std%U0%X0 %1,%0
7161    ld%U1%X1 %0,%1
7162    mr %0,%1
7163    mt%0 %1
7164    mf%1 %0
7165    #
7166    #
7167    #
7168    nop"
7169   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7170    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7172 (define_expand "mov<mode>"
7173   [(set (match_operand:FMOVE128 0 "general_operand" "")
7174         (match_operand:FMOVE128 1 "any_operand" ""))]
7175   ""
7176   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7178 ;; It's important to list Y->r and r->Y before r->r because otherwise
7179 ;; reload, given m->r, will try to pick r->r and reload it, which
7180 ;; doesn't make progress.
7182 ;; We can't split little endian direct moves of TDmode, because the words are
7183 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7184 ;; problematical.  Don't allow direct move for this case.
7186 (define_insn_and_split "*mov<mode>_64bit_dm"
7187   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7188         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7189   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7190    && FLOAT128_2REG_P (<MODE>mode)
7191    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7192    && (gpc_reg_operand (operands[0], <MODE>mode)
7193        || gpc_reg_operand (operands[1], <MODE>mode))"
7194   "#"
7195   "&& reload_completed"
7196   [(pc)]
7197 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7198   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7200 (define_insn_and_split "*movtd_64bit_nodm"
7201   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7202         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7203   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7204    && (gpc_reg_operand (operands[0], TDmode)
7205        || gpc_reg_operand (operands[1], TDmode))"
7206   "#"
7207   "&& reload_completed"
7208   [(pc)]
7209 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7210   [(set_attr "length" "8,8,8,12,12,8")])
7212 (define_insn_and_split "*mov<mode>_32bit"
7213   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7214         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7215   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7216    && (FLOAT128_2REG_P (<MODE>mode)
7217        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7218        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7219    && (gpc_reg_operand (operands[0], <MODE>mode)
7220        || gpc_reg_operand (operands[1], <MODE>mode))"
7221   "#"
7222   "&& reload_completed"
7223   [(pc)]
7224 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7225   [(set_attr "length" "8,8,8,8,20,20,16")])
7227 (define_insn_and_split "*mov<mode>_softfloat"
7228   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7229         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7230   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7231    && (gpc_reg_operand (operands[0], <MODE>mode)
7232        || gpc_reg_operand (operands[1], <MODE>mode))"
7233   "#"
7234   "&& reload_completed"
7235   [(pc)]
7236 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7237   [(set_attr "length" "20,20,16")])
7239 (define_expand "extenddf<mode>2"
7240   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7241         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7242   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7243    && TARGET_LONG_DOUBLE_128"
7245   if (FLOAT128_IEEE_P (<MODE>mode))
7246     rs6000_expand_float128_convert (operands[0], operands[1], false);
7247   else if (TARGET_E500_DOUBLE)
7248     {
7249       gcc_assert (<MODE>mode == TFmode);
7250       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7251     }
7252   else if (TARGET_VSX)
7253     {
7254       if (<MODE>mode == TFmode)
7255         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7256       else if (<MODE>mode == IFmode)
7257         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7258       else
7259         gcc_unreachable ();
7260     }
7261    else
7262     {
7263       rtx zero = gen_reg_rtx (DFmode);
7264       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7266       if (<MODE>mode == TFmode)
7267         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7268       else if (<MODE>mode == IFmode)
7269         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7270       else
7271         gcc_unreachable ();
7272     }
7273   DONE;
7276 ;; Allow memory operands for the source to be created by the combiner.
7277 (define_insn_and_split "extenddf<mode>2_fprs"
7278   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7279         (float_extend:IBM128
7280          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7281    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7282   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7283    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7284   "#"
7285   "&& reload_completed"
7286   [(set (match_dup 3) (match_dup 1))
7287    (set (match_dup 4) (match_dup 2))]
7289   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7290   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7292   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7293   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7296 (define_insn_and_split "extenddf<mode>2_vsx"
7297   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7298         (float_extend:IBM128
7299          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7300   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7301   "#"
7302   "&& reload_completed"
7303   [(set (match_dup 2) (match_dup 1))
7304    (set (match_dup 3) (match_dup 4))]
7306   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7307   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7309   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7310   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7311   operands[4] = CONST0_RTX (DFmode);
7314 (define_expand "extendsf<mode>2"
7315   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7316         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7317   "TARGET_HARD_FLOAT
7318    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7319    && TARGET_LONG_DOUBLE_128"
7321   if (FLOAT128_IEEE_P (<MODE>mode))
7322     rs6000_expand_float128_convert (operands[0], operands[1], false);
7323   else
7324     {
7325       rtx tmp = gen_reg_rtx (DFmode);
7326       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7327       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7328     }
7329   DONE;
7332 (define_expand "trunc<mode>df2"
7333   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7334         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7335   "TARGET_HARD_FLOAT
7336    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7337    && TARGET_LONG_DOUBLE_128"
7339   if (FLOAT128_IEEE_P (<MODE>mode))
7340     {
7341       rs6000_expand_float128_convert (operands[0], operands[1], false);
7342       DONE;
7343     }
7346 (define_insn_and_split "trunc<mode>df2_internal1"
7347   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7348         (float_truncate:DF
7349          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7350   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7351    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7352   "@
7353    #
7354    fmr %0,%1"
7355   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7356   [(const_int 0)]
7358   emit_note (NOTE_INSN_DELETED);
7359   DONE;
7361   [(set_attr "type" "fpsimple")])
7363 (define_insn "trunc<mode>df2_internal2"
7364   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7365         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7366   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7367    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7368   "fadd %0,%1,%L1"
7369   [(set_attr "type" "fp")
7370    (set_attr "fp_type" "fp_addsub_d")])
7372 (define_expand "trunc<mode>sf2"
7373   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7374         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7375   "TARGET_HARD_FLOAT
7376    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7377    && TARGET_LONG_DOUBLE_128"
7379   if (FLOAT128_IEEE_P (<MODE>mode))
7380     rs6000_expand_float128_convert (operands[0], operands[1], false);
7381   else if (TARGET_E500_DOUBLE)
7382     {
7383       gcc_assert (<MODE>mode == TFmode);
7384       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7385     }
7386   else if (<MODE>mode == TFmode)
7387     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7388   else if (<MODE>mode == IFmode)
7389     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7390   else
7391     gcc_unreachable ();
7392   DONE;
7395 (define_insn_and_split "trunc<mode>sf2_fprs"
7396   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7397         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7398    (clobber (match_scratch:DF 2 "=d"))]
7399   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7400    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7401   "#"
7402   "&& reload_completed"
7403   [(set (match_dup 2)
7404         (float_truncate:DF (match_dup 1)))
7405    (set (match_dup 0)
7406         (float_truncate:SF (match_dup 2)))]
7407   "")
7409 (define_expand "floatsi<mode>2"
7410   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7411         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7412   "TARGET_HARD_FLOAT
7413    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7414    && TARGET_LONG_DOUBLE_128"
7416   if (FLOAT128_IEEE_P (<MODE>mode))
7417     rs6000_expand_float128_convert (operands[0], operands[1], false);
7418   else
7419     {
7420       rtx tmp = gen_reg_rtx (DFmode);
7421       expand_float (tmp, operands[1], false);
7422       if (<MODE>mode == TFmode)
7423         emit_insn (gen_extenddftf2 (operands[0], tmp));
7424       else if (<MODE>mode == IFmode)
7425         emit_insn (gen_extenddfif2 (operands[0], tmp));
7426       else
7427         gcc_unreachable ();
7428     }
7429   DONE;
7432 ; fadd, but rounding towards zero.
7433 ; This is probably not the optimal code sequence.
7434 (define_insn "fix_trunc_helper<mode>"
7435   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7436         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7437                    UNSPEC_FIX_TRUNC_TF))
7438    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7439   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7440    && FLOAT128_IBM_P (<MODE>mode)"
7441   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7442   [(set_attr "type" "fp")
7443    (set_attr "length" "20")])
7445 (define_expand "fix_trunc<mode>si2"
7446   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7447         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7448   "TARGET_HARD_FLOAT
7449    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7451   if (FLOAT128_IEEE_P (<MODE>mode))
7452     rs6000_expand_float128_convert (operands[0], operands[1], false);
7453   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7454     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7455   else if (<MODE>mode == TFmode)
7456     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7457   else if (<MODE>mode == IFmode)
7458     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7459   else
7460     gcc_unreachable ();
7461   DONE;
7464 (define_expand "fix_trunc<mode>si2_fprs"
7465   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7466                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7467               (clobber (match_dup 2))
7468               (clobber (match_dup 3))
7469               (clobber (match_dup 4))
7470               (clobber (match_dup 5))])]
7471   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7473   operands[2] = gen_reg_rtx (DFmode);
7474   operands[3] = gen_reg_rtx (DFmode);
7475   operands[4] = gen_reg_rtx (DImode);
7476   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7479 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7480   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7481         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7482    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7483    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7484    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7485    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7486   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7487   "#"
7488   ""
7489   [(pc)]
7491   rtx lowword;
7492   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7493                                          operands[3]));
7495   gcc_assert (MEM_P (operands[5]));
7496   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7498   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7499   emit_move_insn (operands[5], operands[4]);
7500   emit_move_insn (operands[0], lowword);
7501   DONE;
7504 (define_expand "fix_trunc<mode>di2"
7505   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7506         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7507   "TARGET_FLOAT128_TYPE"
7509   rs6000_expand_float128_convert (operands[0], operands[1], false);
7510   DONE;
7513 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7514   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7515         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7516   "TARGET_FLOAT128_TYPE"
7518   rs6000_expand_float128_convert (operands[0], operands[1], true);
7519   DONE;
7522 (define_expand "floatdi<mode>2"
7523   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7524         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7525   "TARGET_FLOAT128_TYPE"
7527   rs6000_expand_float128_convert (operands[0], operands[1], false);
7528   DONE;
7531 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7532   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7533         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7534   "TARGET_FLOAT128_TYPE"
7536   rs6000_expand_float128_convert (operands[0], operands[1], true);
7537   DONE;
7540 (define_expand "neg<mode>2"
7541   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7542         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7543   "FLOAT128_IEEE_P (<MODE>mode)
7544    || (FLOAT128_IBM_P (<MODE>mode)
7545        && TARGET_HARD_FLOAT
7546        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7547   "
7549   if (FLOAT128_IEEE_P (<MODE>mode))
7550     {
7551       if (TARGET_FLOAT128_HW)
7552         {
7553           if (<MODE>mode == TFmode)
7554             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7555           else if (<MODE>mode == KFmode)
7556             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7557           else
7558             gcc_unreachable ();
7559         }
7560       else if (TARGET_FLOAT128_TYPE)
7561         {
7562           if (<MODE>mode == TFmode)
7563             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7564           else if (<MODE>mode == KFmode)
7565             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7566           else
7567             gcc_unreachable ();
7568         }
7569       else
7570         {
7571           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7572           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7573                                                 <MODE>mode, 1,
7574                                                 operands[1], <MODE>mode);
7576           if (target && !rtx_equal_p (target, operands[0]))
7577             emit_move_insn (operands[0], target);
7578         }
7579       DONE;
7580     }
7583 (define_insn "neg<mode>2_internal"
7584   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7585         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7586   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7587   "*
7589   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7590     return \"fneg %L0,%L1\;fneg %0,%1\";
7591   else
7592     return \"fneg %0,%1\;fneg %L0,%L1\";
7594   [(set_attr "type" "fpsimple")
7595    (set_attr "length" "8")])
7597 (define_expand "abs<mode>2"
7598   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7599         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7600   "FLOAT128_IEEE_P (<MODE>mode)
7601    || (FLOAT128_IBM_P (<MODE>mode)
7602        && TARGET_HARD_FLOAT
7603        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7604   "
7606   rtx label;
7608   if (FLOAT128_IEEE_P (<MODE>mode))
7609     {
7610       if (TARGET_FLOAT128_HW)
7611         {
7612           if (<MODE>mode == TFmode)
7613             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7614           else if (<MODE>mode == KFmode)
7615             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7616           else
7617             FAIL;
7618           DONE;
7619         }
7620       else if (TARGET_FLOAT128_TYPE)
7621         {
7622           if (<MODE>mode == TFmode)
7623             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7624           else if (<MODE>mode == KFmode)
7625             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7626           else
7627             FAIL;
7628           DONE;
7629         }
7630       else
7631         FAIL;
7632     }
7634   label = gen_label_rtx ();
7635   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7636     {
7637       if (flag_finite_math_only && !flag_trapping_math)
7638         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7639       else
7640         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7641     }
7642   else if (<MODE>mode == TFmode)
7643     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7644   else if (<MODE>mode == TFmode)
7645     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7646   else
7647     FAIL;
7648   emit_label (label);
7649   DONE;
7652 (define_expand "abs<mode>2_internal"
7653   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7654         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7655    (set (match_dup 3) (match_dup 5))
7656    (set (match_dup 5) (abs:DF (match_dup 5)))
7657    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7658    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7659                            (label_ref (match_operand 2 "" ""))
7660                            (pc)))
7661    (set (match_dup 6) (neg:DF (match_dup 6)))]
7662   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7663    && TARGET_LONG_DOUBLE_128"
7664   "
7666   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7667   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7668   operands[3] = gen_reg_rtx (DFmode);
7669   operands[4] = gen_reg_rtx (CCFPmode);
7670   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7671   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7675 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7676 ;; register
7678 (define_expand "ieee_128bit_negative_zero"
7679   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7680   "TARGET_FLOAT128_TYPE"
7682   rtvec v = rtvec_alloc (16);
7683   int i, high;
7685   for (i = 0; i < 16; i++)
7686     RTVEC_ELT (v, i) = const0_rtx;
7688   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7689   RTVEC_ELT (v, high) = GEN_INT (0x80);
7691   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7692   DONE;
7695 ;; IEEE 128-bit negate
7697 ;; We have 2 insns here for negate and absolute value.  The first uses
7698 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7699 ;; insns, and second insn after the first split pass loads up the bit to
7700 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7701 ;; neg/abs to create the constant just once.
7703 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7704   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7705         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7706    (clobber (match_scratch:V16QI 2 "=v"))]
7707   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7708   "#"
7709   "&& 1"
7710   [(parallel [(set (match_dup 0)
7711                    (neg:IEEE128 (match_dup 1)))
7712               (use (match_dup 2))])]
7714   if (GET_CODE (operands[2]) == SCRATCH)
7715     operands[2] = gen_reg_rtx (V16QImode);
7717   operands[3] = gen_reg_rtx (V16QImode);
7718   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7720   [(set_attr "length" "8")
7721    (set_attr "type" "vecsimple")])
7723 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7724   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7725         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7726    (use (match_operand:V16QI 2 "register_operand" "v"))]
7727   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7728   "xxlxor %x0,%x1,%x2"
7729   [(set_attr "type" "veclogical")])
7731 ;; IEEE 128-bit absolute value
7732 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7733   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7734         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7735    (clobber (match_scratch:V16QI 2 "=v"))]
7736   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7737   "#"
7738   "&& 1"
7739   [(parallel [(set (match_dup 0)
7740                    (abs:IEEE128 (match_dup 1)))
7741               (use (match_dup 2))])]
7743   if (GET_CODE (operands[2]) == SCRATCH)
7744     operands[2] = gen_reg_rtx (V16QImode);
7746   operands[3] = gen_reg_rtx (V16QImode);
7747   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7749   [(set_attr "length" "8")
7750    (set_attr "type" "vecsimple")])
7752 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7753   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7754         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7755    (use (match_operand:V16QI 2 "register_operand" "v"))]
7756   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7757   "xxlandc %x0,%x1,%x2"
7758   [(set_attr "type" "veclogical")])
7760 ;; IEEE 128-bit negative absolute value
7761 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7762   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7763         (neg:IEEE128
7764          (abs:IEEE128
7765           (match_operand:IEEE128 1 "register_operand" "wa"))))
7766    (clobber (match_scratch:V16QI 2 "=v"))]
7767   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
7768    && FLOAT128_IEEE_P (<MODE>mode)"
7769   "#"
7770   "&& 1"
7771   [(parallel [(set (match_dup 0)
7772                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7773               (use (match_dup 2))])]
7775   if (GET_CODE (operands[2]) == SCRATCH)
7776     operands[2] = gen_reg_rtx (V16QImode);
7778   operands[3] = gen_reg_rtx (V16QImode);
7779   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7781   [(set_attr "length" "8")
7782    (set_attr "type" "vecsimple")])
7784 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7785   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7786         (neg:IEEE128
7787          (abs:IEEE128
7788           (match_operand:IEEE128 1 "register_operand" "wa"))))
7789    (use (match_operand:V16QI 2 "register_operand" "v"))]
7790   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7791   "xxlor %x0,%x1,%x2"
7792   [(set_attr "type" "veclogical")])
7794 ;; Float128 conversion functions.  These expand to library function calls.
7795 ;; We use expand to convert from IBM double double to IEEE 128-bit
7796 ;; and trunc for the opposite.
7797 (define_expand "extendiftf2"
7798   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7799         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7800   "TARGET_FLOAT128_TYPE"
7802   rs6000_expand_float128_convert (operands[0], operands[1], false);
7803   DONE;
7806 (define_expand "extendifkf2"
7807   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7808         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7809   "TARGET_FLOAT128_TYPE"
7811   rs6000_expand_float128_convert (operands[0], operands[1], false);
7812   DONE;
7815 (define_expand "extendtfkf2"
7816   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7817         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7818   "TARGET_FLOAT128_TYPE"
7820   rs6000_expand_float128_convert (operands[0], operands[1], false);
7821   DONE;
7824 (define_expand "trunciftf2"
7825   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7826         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7827   "TARGET_FLOAT128_TYPE"
7829   rs6000_expand_float128_convert (operands[0], operands[1], false);
7830   DONE;
7833 (define_expand "truncifkf2"
7834   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7835         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7836   "TARGET_FLOAT128_TYPE"
7838   rs6000_expand_float128_convert (operands[0], operands[1], false);
7839   DONE;
7842 (define_expand "trunckftf2"
7843   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7844         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7845   "TARGET_FLOAT128_TYPE"
7847   rs6000_expand_float128_convert (operands[0], operands[1], false);
7848   DONE;
7851 (define_expand "trunctfif2"
7852   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7853         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7854   "TARGET_FLOAT128_TYPE"
7856   rs6000_expand_float128_convert (operands[0], operands[1], false);
7857   DONE;
7861 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7862 ;; must have 3 arguments, and scratch register constraint must be a single
7863 ;; constraint.
7865 ;; Reload patterns to support gpr load/store with misaligned mem.
7866 ;; and multiple gpr load/store at offset >= 0xfffc
7867 (define_expand "reload_<mode>_store"
7868   [(parallel [(match_operand 0 "memory_operand" "=m")
7869               (match_operand 1 "gpc_reg_operand" "r")
7870               (match_operand:GPR 2 "register_operand" "=&b")])]
7871   ""
7873   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7874   DONE;
7877 (define_expand "reload_<mode>_load"
7878   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7879               (match_operand 1 "memory_operand" "m")
7880               (match_operand:GPR 2 "register_operand" "=b")])]
7881   ""
7883   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7884   DONE;
7888 ;; Reload patterns for various types using the vector registers.  We may need
7889 ;; an additional base register to convert the reg+offset addressing to reg+reg
7890 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7891 ;; index register for gpr registers.
7892 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7893   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7894               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7895               (match_operand:P 2 "register_operand" "=b")])]
7896   "<P:tptrsize>"
7898   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7899   DONE;
7902 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7903   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7904               (match_operand:RELOAD 1 "memory_operand" "m")
7905               (match_operand:P 2 "register_operand" "=b")])]
7906   "<P:tptrsize>"
7908   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7909   DONE;
7913 ;; Reload sometimes tries to move the address to a GPR, and can generate
7914 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7915 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7917 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7918   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7919         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7920                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7921                (const_int -16)))]
7922   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7923   "#"
7924   "&& reload_completed"
7925   [(set (match_dup 0)
7926         (plus:P (match_dup 1)
7927                 (match_dup 2)))
7928    (set (match_dup 0)
7929         (and:P (match_dup 0)
7930                (const_int -16)))])
7932 ;; Power8 merge instructions to allow direct move to/from floating point
7933 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7934 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7935 ;; value, since it is allocated in reload and not all of the flow information
7936 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7937 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7938 ;; schedule other instructions between the two instructions.
7940 (define_insn "p8_fmrgow_<mode>"
7941   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7942         (unspec:FMOVE64X [
7943                 (match_operand:DF 1 "register_operand" "d")
7944                 (match_operand:DF 2 "register_operand" "d")]
7945                          UNSPEC_P8V_FMRGOW))]
7946   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7947   "fmrgow %0,%1,%2"
7948   [(set_attr "type" "fpsimple")])
7950 (define_insn "p8_mtvsrwz"
7951   [(set (match_operand:DF 0 "register_operand" "=d")
7952         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7953                    UNSPEC_P8V_MTVSRWZ))]
7954   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7955   "mtvsrwz %x0,%1"
7956   [(set_attr "type" "mftgpr")])
7958 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7959   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7960         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7961                          UNSPEC_P8V_RELOAD_FROM_GPR))
7962    (clobber (match_operand:IF 2 "register_operand" "=d"))]
7963   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7964   "#"
7965   "&& reload_completed"
7966   [(const_int 0)]
7968   rtx dest = operands[0];
7969   rtx src = operands[1];
7970   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7971   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7972   rtx gpr_hi_reg = gen_highpart (SImode, src);
7973   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7975   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7976   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7977   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7978   DONE;
7980   [(set_attr "length" "12")
7981    (set_attr "type" "three")])
7983 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7984 (define_insn "p8_mtvsrd_df"
7985   [(set (match_operand:DF 0 "register_operand" "=wa")
7986         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7987                    UNSPEC_P8V_MTVSRD))]
7988   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7989   "mtvsrd %x0,%1"
7990   [(set_attr "type" "mftgpr")])
7992 (define_insn "p8_xxpermdi_<mode>"
7993   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7994         (unspec:FMOVE128_GPR [
7995                 (match_operand:DF 1 "register_operand" "wa")
7996                 (match_operand:DF 2 "register_operand" "wa")]
7997                 UNSPEC_P8V_XXPERMDI))]
7998   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7999   "xxpermdi %x0,%x1,%x2,0"
8000   [(set_attr "type" "vecperm")])
8002 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8003   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8004         (unspec:FMOVE128_GPR
8005          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8006          UNSPEC_P8V_RELOAD_FROM_GPR))
8007    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8008   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8009   "#"
8010   "&& reload_completed"
8011   [(const_int 0)]
8013   rtx dest = operands[0];
8014   rtx src = operands[1];
8015   /* You might think that we could use op0 as one temp and a DF clobber
8016      as op2, but you'd be wrong.  Secondary reload move patterns don't
8017      check for overlap of the clobber and the destination.  */
8018   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8019   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8020   rtx gpr_hi_reg = gen_highpart (DImode, src);
8021   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8023   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8024   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8025   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8026   DONE;
8028   [(set_attr "length" "12")
8029    (set_attr "type" "three")])
8031 (define_split
8032   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8033         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8034   "reload_completed
8035    && (int_reg_operand (operands[0], <MODE>mode)
8036        || int_reg_operand (operands[1], <MODE>mode))
8037    && (!TARGET_DIRECT_MOVE_128
8038        || (!vsx_register_operand (operands[0], <MODE>mode)
8039            && !vsx_register_operand (operands[1], <MODE>mode)))"
8040   [(pc)]
8041 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8043 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8044 ;; type is stored internally as double precision in the VSX registers, we have
8045 ;; to convert it from the vector format.
8046 (define_insn "p8_mtvsrd_sf"
8047   [(set (match_operand:SF 0 "register_operand" "=wa")
8048         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8049                    UNSPEC_P8V_MTVSRD))]
8050   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8051   "mtvsrd %x0,%1"
8052   [(set_attr "type" "mftgpr")])
8054 (define_insn_and_split "reload_vsx_from_gprsf"
8055   [(set (match_operand:SF 0 "register_operand" "=wa")
8056         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8057                    UNSPEC_P8V_RELOAD_FROM_GPR))
8058    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8059   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8060   "#"
8061   "&& reload_completed"
8062   [(const_int 0)]
8064   rtx op0 = operands[0];
8065   rtx op1 = operands[1];
8066   rtx op2 = operands[2];
8067   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8069   /* Move SF value to upper 32-bits for xscvspdpn.  */
8070   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8071   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8072   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8073   DONE;
8075   [(set_attr "length" "8")
8076    (set_attr "type" "two")])
8078 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8079 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8080 ;; and then doing a move of that.
8081 (define_insn "p8_mfvsrd_3_<mode>"
8082   [(set (match_operand:DF 0 "register_operand" "=r")
8083         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8084                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8085   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8086   "mfvsrd %0,%x1"
8087   [(set_attr "type" "mftgpr")])
8089 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8090   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8091         (unspec:FMOVE128_GPR
8092          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8093          UNSPEC_P8V_RELOAD_FROM_VSX))
8094    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8095   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8096   "#"
8097   "&& reload_completed"
8098   [(const_int 0)]
8100   rtx dest = operands[0];
8101   rtx src = operands[1];
8102   rtx tmp = operands[2];
8103   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8104   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8106   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8107   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8108   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8109   DONE;
8111   [(set_attr "length" "12")
8112    (set_attr "type" "three")])
8114 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8115 ;; type is stored internally as double precision, we have to convert it to the
8116 ;; vector format.
8118 (define_insn_and_split "reload_gpr_from_vsxsf"
8119   [(set (match_operand:SF 0 "register_operand" "=r")
8120         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8121                    UNSPEC_P8V_RELOAD_FROM_VSX))
8122    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8123   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8124   "#"
8125   "&& reload_completed"
8126   [(const_int 0)]
8128   rtx op0 = operands[0];
8129   rtx op1 = operands[1];
8130   rtx op2 = operands[2];
8131   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8133   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8134   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8135   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8136   DONE;
8138   [(set_attr "length" "12")
8139    (set_attr "type" "three")])
8141 (define_insn "p8_mfvsrd_4_disf"
8142   [(set (match_operand:DI 0 "register_operand" "=r")
8143         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8144                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8145   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8146   "mfvsrd %0,%x1"
8147   [(set_attr "type" "mftgpr")])
8150 ;; Next come the multi-word integer load and store and the load and store
8151 ;; multiple insns.
8153 ;; List r->r after r->Y, otherwise reload will try to reload a
8154 ;; non-offsettable address by using r->r which won't make progress.
8155 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8156 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8158 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8159 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8160 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8161 ;;        AVX const  
8163 (define_insn "*movdi_internal32"
8164   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8165          "=Y,        r,         r,         ^m,        ^d,         ^d,
8166           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8167           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8168           *wv")
8170         (match_operand:DI 1 "input_operand"
8171           "r,        Y,         r,         d,         m,          d,
8172            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8173            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8174            wB"))]
8176   "! TARGET_POWERPC64
8177    && (gpc_reg_operand (operands[0], DImode)
8178        || gpc_reg_operand (operands[1], DImode))"
8179   "@
8180    #
8181    #
8182    #
8183    stfd%U0%X0 %1,%0
8184    lfd%U1%X1 %0,%1
8185    fmr %0,%1
8186    #
8187    stxsd %1,%0
8188    stxsdx %x1,%y0
8189    lxsd %0,%1
8190    lxsdx %x0,%y1
8191    xxlor %x0,%x1,%x1
8192    xxspltib %x0,0
8193    xxspltib %x0,255
8194    vspltisw %0,%1
8195    xxlxor %x0,%x0,%x0
8196    xxlorc %x0,%x0,%x0
8197    #
8198    #"
8199   [(set_attr "type"
8200                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8201                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8202                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8203                 vecsimple")
8204    (set_attr "size" "64")])
8206 (define_split
8207   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8208         (match_operand:DI 1 "const_int_operand" ""))]
8209   "! TARGET_POWERPC64 && reload_completed
8210    && gpr_or_gpr_p (operands[0], operands[1])
8211    && !direct_move_p (operands[0], operands[1])"
8212   [(set (match_dup 2) (match_dup 4))
8213    (set (match_dup 3) (match_dup 1))]
8214   "
8216   HOST_WIDE_INT value = INTVAL (operands[1]);
8217   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8218                                        DImode);
8219   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8220                                        DImode);
8221   operands[4] = GEN_INT (value >> 32);
8222   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8225 (define_split
8226   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8227         (match_operand:DIFD 1 "input_operand" ""))]
8228   "reload_completed && !TARGET_POWERPC64
8229    && gpr_or_gpr_p (operands[0], operands[1])
8230    && !direct_move_p (operands[0], operands[1])"
8231   [(pc)]
8232 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8234 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8235 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8236 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8237 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8238 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8239 (define_insn "*movdi_internal64"
8240   [(set (match_operand:DI 0 "nonimmediate_operand"
8241                "=Y,        r,         r,         r,         r,          r,
8242                 ^m,        ^d,        ^d,        ^Y,        $Z,         $wb,
8243                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8244                 *wi,       *wv,       *wv,       r,         *h,         *h,
8245                 ?*r,       ?*wg,      ?*r,       ?*wj")
8247         (match_operand:DI 1 "input_operand"
8248                 "r,        Y,         r,         I,         L,          nF,
8249                  d,        m,         d,         wb,        wv,         wY,
8250                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8251                  wM,       wS,        wB,        *h,        r,          0,
8252                  wg,       r,         wj,        r"))]
8254   "TARGET_POWERPC64
8255    && (gpc_reg_operand (operands[0], DImode)
8256        || gpc_reg_operand (operands[1], DImode))"
8257   "@
8258    std%U0%X0 %1,%0
8259    ld%U1%X1 %0,%1
8260    mr %0,%1
8261    li %0,%1
8262    lis %0,%v1
8263    #
8264    stfd%U0%X0 %1,%0
8265    lfd%U1%X1 %0,%1
8266    fmr %0,%1
8267    stxsd %1,%0
8268    stxsdx %x1,%y0
8269    lxsd %0,%1
8270    lxsdx %x0,%y1
8271    xxlor %x0,%x1,%x1
8272    xxspltib %x0,0
8273    xxspltib %x0,255
8274    #
8275    xxlxor %x0,%x0,%x0
8276    xxlorc %x0,%x0,%x0
8277    #
8278    #
8279    mf%1 %0
8280    mt%0 %1
8281    nop
8282    mftgpr %0,%1
8283    mffgpr %0,%1
8284    mfvsrd %0,%x1
8285    mtvsrd %x0,%1"
8286   [(set_attr "type"
8287                "store,      load,       *,         *,         *,         *,
8288                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8289                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8290                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8291                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8293    (set_attr "size" "64")
8294    (set_attr "length"
8295                "4,         4,         4,         4,         4,          20,
8296                 4,         4,         4,         4,         4,          4,
8297                 4,         4,         4,         4,         4,          8,
8298                 8,         4,         4,         4,         4,          4,
8299                 4,         4,         4,         4")])
8301 ; Some DImode loads are best done as a load of -1 followed by a mask
8302 ; instruction.
8303 (define_split
8304   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8305         (match_operand:DI 1 "const_int_operand"))]
8306   "TARGET_POWERPC64
8307    && num_insns_constant (operands[1], DImode) > 1
8308    && rs6000_is_valid_and_mask (operands[1], DImode)"
8309   [(set (match_dup 0)
8310         (const_int -1))
8311    (set (match_dup 0)
8312         (and:DI (match_dup 0)
8313                 (match_dup 1)))]
8314   "")
8316 ;; Split a load of a large constant into the appropriate five-instruction
8317 ;; sequence.  Handle anything in a constant number of insns.
8318 ;; When non-easy constants can go in the TOC, this should use
8319 ;; easy_fp_constant predicate.
8320 (define_split
8321   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8322         (match_operand:DI 1 "const_int_operand" ""))]
8323   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8324   [(set (match_dup 0) (match_dup 2))
8325    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8326   "
8328   if (rs6000_emit_set_const (operands[0], operands[1]))
8329     DONE;
8330   else
8331     FAIL;
8334 (define_split
8335   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8336         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8337   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8338   [(set (match_dup 0) (match_dup 2))
8339    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8340   "
8342   if (rs6000_emit_set_const (operands[0], operands[1]))
8343     DONE;
8344   else
8345     FAIL;
8348 (define_split
8349   [(set (match_operand:DI 0 "altivec_register_operand" "")
8350         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8351   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8352   [(const_int 0)]
8354   rtx op0 = operands[0];
8355   rtx op1 = operands[1];
8356   int r = REGNO (op0);
8357   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8359   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8360   if (op1 != const0_rtx && op1 != constm1_rtx)
8361     {
8362       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8363       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8364     }
8365   DONE;
8368 ;; Split integer constants that can be loaded with XXSPLTIB and a
8369 ;; sign extend operation.
8370 (define_split
8371   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8372         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8373   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8374   [(const_int 0)]
8376   rtx op0 = operands[0];
8377   rtx op1 = operands[1];
8378   int r = REGNO (op0);
8379   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8381   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8382   if (<MODE>mode == DImode)
8383     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8384   else if (<MODE>mode == SImode)
8385     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8386   else if (<MODE>mode == HImode)
8387     {
8388       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8389       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8390     }
8391   DONE;
8395 ;; TImode/PTImode is similar, except that we usually want to compute the
8396 ;; address into a register and use lsi/stsi (the exception is during reload).
8398 (define_insn "*mov<mode>_string"
8399   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8400         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8401   "! TARGET_POWERPC64
8402    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8403    && (gpc_reg_operand (operands[0], <MODE>mode)
8404        || gpc_reg_operand (operands[1], <MODE>mode))"
8405   "*
8407   switch (which_alternative)
8408     {
8409     default:
8410       gcc_unreachable ();
8411     case 0:
8412       if (TARGET_STRING)
8413         return \"stswi %1,%P0,16\";
8414       /* FALLTHRU */
8415     case 1:
8416       return \"#\";
8417     case 2:
8418       /* If the address is not used in the output, we can use lsi.  Otherwise,
8419          fall through to generating four loads.  */
8420       if (TARGET_STRING
8421           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8422         return \"lswi %0,%P1,16\";
8423       /* fall through */
8424     case 3:
8425     case 4:
8426     case 5:
8427       return \"#\";
8428     }
8430   [(set_attr "type" "store,store,load,load,*,*")
8431    (set_attr "update" "yes")
8432    (set_attr "indexed" "yes")
8433    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8434                                           (const_string "always")
8435                                           (const_string "conditional")))])
8437 (define_insn "*mov<mode>_ppc64"
8438   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8439         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8440   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8441    && (gpc_reg_operand (operands[0], <MODE>mode)
8442        || gpc_reg_operand (operands[1], <MODE>mode)))"
8444   return rs6000_output_move_128bit (operands);
8446   [(set_attr "type" "store,store,load,load,*,*")
8447    (set_attr "length" "8")])
8449 (define_split
8450   [(set (match_operand:TI2 0 "int_reg_operand" "")
8451         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8452   "TARGET_POWERPC64
8453    && (VECTOR_MEM_NONE_P (<MODE>mode)
8454        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8455   [(set (match_dup 2) (match_dup 4))
8456    (set (match_dup 3) (match_dup 5))]
8457   "
8459   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8460                                        <MODE>mode);
8461   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8462                                        <MODE>mode);
8463   if (CONST_WIDE_INT_P (operands[1]))
8464     {
8465       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8466       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8467     }
8468   else if (CONST_INT_P (operands[1]))
8469     {
8470       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8471       operands[5] = operands[1];
8472     }
8473   else
8474     FAIL;
8477 (define_split
8478   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8479         (match_operand:TI2 1 "input_operand" ""))]
8480   "reload_completed
8481    && gpr_or_gpr_p (operands[0], operands[1])
8482    && !direct_move_p (operands[0], operands[1])
8483    && !quad_load_store_p (operands[0], operands[1])"
8484   [(pc)]
8485 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8487 (define_expand "load_multiple"
8488   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8489                           (match_operand:SI 1 "" ""))
8490                      (use (match_operand:SI 2 "" ""))])]
8491   "TARGET_STRING && !TARGET_POWERPC64"
8492   "
8494   int regno;
8495   int count;
8496   rtx op1;
8497   int i;
8499   /* Support only loading a constant number of fixed-point registers from
8500      memory and only bother with this if more than two; the machine
8501      doesn't support more than eight.  */
8502   if (GET_CODE (operands[2]) != CONST_INT
8503       || INTVAL (operands[2]) <= 2
8504       || INTVAL (operands[2]) > 8
8505       || GET_CODE (operands[1]) != MEM
8506       || GET_CODE (operands[0]) != REG
8507       || REGNO (operands[0]) >= 32)
8508     FAIL;
8510   count = INTVAL (operands[2]);
8511   regno = REGNO (operands[0]);
8513   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8514   op1 = replace_equiv_address (operands[1],
8515                                force_reg (SImode, XEXP (operands[1], 0)));
8517   for (i = 0; i < count; i++)
8518     XVECEXP (operands[3], 0, i)
8519       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8520                      adjust_address_nv (op1, SImode, i * 4));
8523 (define_insn "*ldmsi8"
8524   [(match_parallel 0 "load_multiple_operation"
8525     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8526           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8527      (set (match_operand:SI 3 "gpc_reg_operand" "")
8528           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8529      (set (match_operand:SI 4 "gpc_reg_operand" "")
8530           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8531      (set (match_operand:SI 5 "gpc_reg_operand" "")
8532           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8533      (set (match_operand:SI 6 "gpc_reg_operand" "")
8534           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8535      (set (match_operand:SI 7 "gpc_reg_operand" "")
8536           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8537      (set (match_operand:SI 8 "gpc_reg_operand" "")
8538           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8539      (set (match_operand:SI 9 "gpc_reg_operand" "")
8540           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8541   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8542   "*
8543 { return rs6000_output_load_multiple (operands); }"
8544   [(set_attr "type" "load")
8545    (set_attr "update" "yes")
8546    (set_attr "indexed" "yes")
8547    (set_attr "length" "32")])
8549 (define_insn "*ldmsi7"
8550   [(match_parallel 0 "load_multiple_operation"
8551     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8552           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8553      (set (match_operand:SI 3 "gpc_reg_operand" "")
8554           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8555      (set (match_operand:SI 4 "gpc_reg_operand" "")
8556           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8557      (set (match_operand:SI 5 "gpc_reg_operand" "")
8558           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8559      (set (match_operand:SI 6 "gpc_reg_operand" "")
8560           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8561      (set (match_operand:SI 7 "gpc_reg_operand" "")
8562           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8563      (set (match_operand:SI 8 "gpc_reg_operand" "")
8564           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8565   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8566   "*
8567 { return rs6000_output_load_multiple (operands); }"
8568   [(set_attr "type" "load")
8569    (set_attr "update" "yes")
8570    (set_attr "indexed" "yes")
8571    (set_attr "length" "32")])
8573 (define_insn "*ldmsi6"
8574   [(match_parallel 0 "load_multiple_operation"
8575     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8576           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8577      (set (match_operand:SI 3 "gpc_reg_operand" "")
8578           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8579      (set (match_operand:SI 4 "gpc_reg_operand" "")
8580           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8581      (set (match_operand:SI 5 "gpc_reg_operand" "")
8582           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8583      (set (match_operand:SI 6 "gpc_reg_operand" "")
8584           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8585      (set (match_operand:SI 7 "gpc_reg_operand" "")
8586           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8587   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8588   "*
8589 { return rs6000_output_load_multiple (operands); }"
8590   [(set_attr "type" "load")
8591    (set_attr "update" "yes")
8592    (set_attr "indexed" "yes")
8593    (set_attr "length" "32")])
8595 (define_insn "*ldmsi5"
8596   [(match_parallel 0 "load_multiple_operation"
8597     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8598           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8599      (set (match_operand:SI 3 "gpc_reg_operand" "")
8600           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8601      (set (match_operand:SI 4 "gpc_reg_operand" "")
8602           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8603      (set (match_operand:SI 5 "gpc_reg_operand" "")
8604           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8605      (set (match_operand:SI 6 "gpc_reg_operand" "")
8606           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8607   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8608   "*
8609 { return rs6000_output_load_multiple (operands); }"
8610   [(set_attr "type" "load")
8611    (set_attr "update" "yes")
8612    (set_attr "indexed" "yes")
8613    (set_attr "length" "32")])
8615 (define_insn "*ldmsi4"
8616   [(match_parallel 0 "load_multiple_operation"
8617     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8618           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8619      (set (match_operand:SI 3 "gpc_reg_operand" "")
8620           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8621      (set (match_operand:SI 4 "gpc_reg_operand" "")
8622           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8623      (set (match_operand:SI 5 "gpc_reg_operand" "")
8624           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8625   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8626   "*
8627 { return rs6000_output_load_multiple (operands); }"
8628   [(set_attr "type" "load")
8629    (set_attr "update" "yes")
8630    (set_attr "indexed" "yes")
8631    (set_attr "length" "32")])
8633 (define_insn "*ldmsi3"
8634   [(match_parallel 0 "load_multiple_operation"
8635     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8636           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8637      (set (match_operand:SI 3 "gpc_reg_operand" "")
8638           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8639      (set (match_operand:SI 4 "gpc_reg_operand" "")
8640           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8641   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8642   "*
8643 { return rs6000_output_load_multiple (operands); }"
8644   [(set_attr "type" "load")
8645    (set_attr "update" "yes")
8646    (set_attr "indexed" "yes")
8647    (set_attr "length" "32")])
8649 (define_expand "store_multiple"
8650   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8651                           (match_operand:SI 1 "" ""))
8652                      (clobber (scratch:SI))
8653                      (use (match_operand:SI 2 "" ""))])]
8654   "TARGET_STRING && !TARGET_POWERPC64"
8655   "
8657   int regno;
8658   int count;
8659   rtx to;
8660   rtx op0;
8661   int i;
8663   /* Support only storing a constant number of fixed-point registers to
8664      memory and only bother with this if more than two; the machine
8665      doesn't support more than eight.  */
8666   if (GET_CODE (operands[2]) != CONST_INT
8667       || INTVAL (operands[2]) <= 2
8668       || INTVAL (operands[2]) > 8
8669       || GET_CODE (operands[0]) != MEM
8670       || GET_CODE (operands[1]) != REG
8671       || REGNO (operands[1]) >= 32)
8672     FAIL;
8674   count = INTVAL (operands[2]);
8675   regno = REGNO (operands[1]);
8677   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8678   to = force_reg (SImode, XEXP (operands[0], 0));
8679   op0 = replace_equiv_address (operands[0], to);
8681   XVECEXP (operands[3], 0, 0)
8682     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8683   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8684                                                  gen_rtx_SCRATCH (SImode));
8686   for (i = 1; i < count; i++)
8687     XVECEXP (operands[3], 0, i + 1)
8688       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8689                      gen_rtx_REG (SImode, regno + i));
8692 (define_insn "*stmsi8"
8693   [(match_parallel 0 "store_multiple_operation"
8694     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8695           (match_operand:SI 2 "gpc_reg_operand" "r"))
8696      (clobber (match_scratch:SI 3 "=X"))
8697      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8698           (match_operand:SI 4 "gpc_reg_operand" "r"))
8699      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8700           (match_operand:SI 5 "gpc_reg_operand" "r"))
8701      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8702           (match_operand:SI 6 "gpc_reg_operand" "r"))
8703      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8704           (match_operand:SI 7 "gpc_reg_operand" "r"))
8705      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8706           (match_operand:SI 8 "gpc_reg_operand" "r"))
8707      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8708           (match_operand:SI 9 "gpc_reg_operand" "r"))
8709      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8710           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8711   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8712   "stswi %2,%1,%O0"
8713   [(set_attr "type" "store")
8714    (set_attr "update" "yes")
8715    (set_attr "indexed" "yes")
8716    (set_attr "cell_micro" "always")])
8718 (define_insn "*stmsi7"
8719   [(match_parallel 0 "store_multiple_operation"
8720     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8721           (match_operand:SI 2 "gpc_reg_operand" "r"))
8722      (clobber (match_scratch:SI 3 "=X"))
8723      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8724           (match_operand:SI 4 "gpc_reg_operand" "r"))
8725      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8726           (match_operand:SI 5 "gpc_reg_operand" "r"))
8727      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8728           (match_operand:SI 6 "gpc_reg_operand" "r"))
8729      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8730           (match_operand:SI 7 "gpc_reg_operand" "r"))
8731      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8732           (match_operand:SI 8 "gpc_reg_operand" "r"))
8733      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8734           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8735   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8736   "stswi %2,%1,%O0"
8737   [(set_attr "type" "store")
8738    (set_attr "update" "yes")
8739    (set_attr "indexed" "yes")
8740    (set_attr "cell_micro" "always")])
8742 (define_insn "*stmsi6"
8743   [(match_parallel 0 "store_multiple_operation"
8744     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8745           (match_operand:SI 2 "gpc_reg_operand" "r"))
8746      (clobber (match_scratch:SI 3 "=X"))
8747      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8748           (match_operand:SI 4 "gpc_reg_operand" "r"))
8749      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8750           (match_operand:SI 5 "gpc_reg_operand" "r"))
8751      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8752           (match_operand:SI 6 "gpc_reg_operand" "r"))
8753      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8754           (match_operand:SI 7 "gpc_reg_operand" "r"))
8755      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8756           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8757   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8758   "stswi %2,%1,%O0"
8759   [(set_attr "type" "store")
8760    (set_attr "update" "yes")
8761    (set_attr "indexed" "yes")
8762    (set_attr "cell_micro" "always")])
8764 (define_insn "*stmsi5"
8765   [(match_parallel 0 "store_multiple_operation"
8766     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8767           (match_operand:SI 2 "gpc_reg_operand" "r"))
8768      (clobber (match_scratch:SI 3 "=X"))
8769      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8770           (match_operand:SI 4 "gpc_reg_operand" "r"))
8771      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8772           (match_operand:SI 5 "gpc_reg_operand" "r"))
8773      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8774           (match_operand:SI 6 "gpc_reg_operand" "r"))
8775      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8776           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8777   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8778   "stswi %2,%1,%O0"
8779   [(set_attr "type" "store")
8780    (set_attr "update" "yes")
8781    (set_attr "indexed" "yes")
8782    (set_attr "cell_micro" "always")])
8784 (define_insn "*stmsi4"
8785   [(match_parallel 0 "store_multiple_operation"
8786     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8787           (match_operand:SI 2 "gpc_reg_operand" "r"))
8788      (clobber (match_scratch:SI 3 "=X"))
8789      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8790           (match_operand:SI 4 "gpc_reg_operand" "r"))
8791      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8792           (match_operand:SI 5 "gpc_reg_operand" "r"))
8793      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8794           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8795   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8796   "stswi %2,%1,%O0"
8797   [(set_attr "type" "store")
8798    (set_attr "update" "yes")
8799    (set_attr "indexed" "yes")
8800    (set_attr "cell_micro" "always")])
8802 (define_insn "*stmsi3"
8803   [(match_parallel 0 "store_multiple_operation"
8804     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8805           (match_operand:SI 2 "gpc_reg_operand" "r"))
8806      (clobber (match_scratch:SI 3 "=X"))
8807      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8808           (match_operand:SI 4 "gpc_reg_operand" "r"))
8809      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8810           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8811   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8812   "stswi %2,%1,%O0"
8813   [(set_attr "type" "store")
8814    (set_attr "update" "yes")
8815    (set_attr "indexed" "yes")
8816    (set_attr "cell_micro" "always")])
8818 (define_expand "setmemsi"
8819   [(parallel [(set (match_operand:BLK 0 "" "")
8820                    (match_operand 2 "const_int_operand" ""))
8821               (use (match_operand:SI 1 "" ""))
8822               (use (match_operand:SI 3 "" ""))])]
8823   ""
8824   "
8826   /* If value to set is not zero, use the library routine.  */
8827   if (operands[2] != const0_rtx)
8828     FAIL;
8830   if (expand_block_clear (operands))
8831     DONE;
8832   else
8833     FAIL;
8836 ;; String/block compare insn.
8837 ;; Argument 0 is the target (result)
8838 ;; Argument 1 is the destination
8839 ;; Argument 2 is the source
8840 ;; Argument 3 is the length
8841 ;; Argument 4 is the alignment
8843 (define_expand "cmpmemsi"
8844   [(parallel [(set (match_operand:SI 0)
8845                (compare:SI (match_operand:BLK 1)
8846                            (match_operand:BLK 2)))
8847               (use (match_operand:SI 3))
8848               (use (match_operand:SI 4))])]
8849   ""
8851   if (expand_block_compare (operands))
8852     DONE;
8853   else  
8854     FAIL;
8857 ;; String/block move insn.
8858 ;; Argument 0 is the destination
8859 ;; Argument 1 is the source
8860 ;; Argument 2 is the length
8861 ;; Argument 3 is the alignment
8863 (define_expand "movmemsi"
8864   [(parallel [(set (match_operand:BLK 0 "" "")
8865                    (match_operand:BLK 1 "" ""))
8866               (use (match_operand:SI 2 "" ""))
8867               (use (match_operand:SI 3 "" ""))])]
8868   ""
8869   "
8871   if (expand_block_move (operands))
8872     DONE;
8873   else
8874     FAIL;
8877 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8878 ;; register allocator doesn't have a clue about allocating 8 word registers.
8879 ;; rD/rS = r5 is preferred, efficient form.
8880 (define_expand "movmemsi_8reg"
8881   [(parallel [(set (match_operand 0 "" "")
8882                    (match_operand 1 "" ""))
8883               (use (match_operand 2 "" ""))
8884               (use (match_operand 3 "" ""))
8885               (clobber (reg:SI  5))
8886               (clobber (reg:SI  6))
8887               (clobber (reg:SI  7))
8888               (clobber (reg:SI  8))
8889               (clobber (reg:SI  9))
8890               (clobber (reg:SI 10))
8891               (clobber (reg:SI 11))
8892               (clobber (reg:SI 12))
8893               (clobber (match_scratch:SI 4 ""))])]
8894   "TARGET_STRING"
8895   "")
8897 (define_insn ""
8898   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8899         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8900    (use (match_operand:SI 2 "immediate_operand" "i"))
8901    (use (match_operand:SI 3 "immediate_operand" "i"))
8902    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8903    (clobber (reg:SI  6))
8904    (clobber (reg:SI  7))
8905    (clobber (reg:SI  8))
8906    (clobber (reg:SI  9))
8907    (clobber (reg:SI 10))
8908    (clobber (reg:SI 11))
8909    (clobber (reg:SI 12))
8910    (clobber (match_scratch:SI 5 "=X"))]
8911   "TARGET_STRING
8912    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8913        || INTVAL (operands[2]) == 0)
8914    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8915    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8916    && REGNO (operands[4]) == 5"
8917   "lswi %4,%1,%2\;stswi %4,%0,%2"
8918   [(set_attr "type" "store")
8919    (set_attr "update" "yes")
8920    (set_attr "indexed" "yes")
8921    (set_attr "cell_micro" "always")
8922    (set_attr "length" "8")])
8924 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8925 ;; register allocator doesn't have a clue about allocating 6 word registers.
8926 ;; rD/rS = r5 is preferred, efficient form.
8927 (define_expand "movmemsi_6reg"
8928   [(parallel [(set (match_operand 0 "" "")
8929                    (match_operand 1 "" ""))
8930               (use (match_operand 2 "" ""))
8931               (use (match_operand 3 "" ""))
8932               (clobber (reg:SI  5))
8933               (clobber (reg:SI  6))
8934               (clobber (reg:SI  7))
8935               (clobber (reg:SI  8))
8936               (clobber (reg:SI  9))
8937               (clobber (reg:SI 10))
8938               (clobber (match_scratch:SI 4 ""))])]
8939   "TARGET_STRING"
8940   "")
8942 (define_insn ""
8943   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8944         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8945    (use (match_operand:SI 2 "immediate_operand" "i"))
8946    (use (match_operand:SI 3 "immediate_operand" "i"))
8947    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8948    (clobber (reg:SI  6))
8949    (clobber (reg:SI  7))
8950    (clobber (reg:SI  8))
8951    (clobber (reg:SI  9))
8952    (clobber (reg:SI 10))
8953    (clobber (match_scratch:SI 5 "=X"))]
8954   "TARGET_STRING
8955    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8956    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8957    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8958    && REGNO (operands[4]) == 5"
8959   "lswi %4,%1,%2\;stswi %4,%0,%2"
8960   [(set_attr "type" "store")
8961    (set_attr "update" "yes")
8962    (set_attr "indexed" "yes")
8963    (set_attr "cell_micro" "always")
8964    (set_attr "length" "8")])
8966 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8967 ;; problems with TImode.
8968 ;; rD/rS = r5 is preferred, efficient form.
8969 (define_expand "movmemsi_4reg"
8970   [(parallel [(set (match_operand 0 "" "")
8971                    (match_operand 1 "" ""))
8972               (use (match_operand 2 "" ""))
8973               (use (match_operand 3 "" ""))
8974               (clobber (reg:SI 5))
8975               (clobber (reg:SI 6))
8976               (clobber (reg:SI 7))
8977               (clobber (reg:SI 8))
8978               (clobber (match_scratch:SI 4 ""))])]
8979   "TARGET_STRING"
8980   "")
8982 (define_insn ""
8983   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8984         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8985    (use (match_operand:SI 2 "immediate_operand" "i"))
8986    (use (match_operand:SI 3 "immediate_operand" "i"))
8987    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8988    (clobber (reg:SI 6))
8989    (clobber (reg:SI 7))
8990    (clobber (reg:SI 8))
8991    (clobber (match_scratch:SI 5 "=X"))]
8992   "TARGET_STRING
8993    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8994    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8995    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8996    && REGNO (operands[4]) == 5"
8997   "lswi %4,%1,%2\;stswi %4,%0,%2"
8998   [(set_attr "type" "store")
8999    (set_attr "update" "yes")
9000    (set_attr "indexed" "yes")
9001    (set_attr "cell_micro" "always")
9002    (set_attr "length" "8")])
9004 ;; Move up to 8 bytes at a time.
9005 (define_expand "movmemsi_2reg"
9006   [(parallel [(set (match_operand 0 "" "")
9007                    (match_operand 1 "" ""))
9008               (use (match_operand 2 "" ""))
9009               (use (match_operand 3 "" ""))
9010               (clobber (match_scratch:DI 4 ""))
9011               (clobber (match_scratch:SI 5 ""))])]
9012   "TARGET_STRING && ! TARGET_POWERPC64"
9013   "")
9015 (define_insn ""
9016   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9017         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9018    (use (match_operand:SI 2 "immediate_operand" "i"))
9019    (use (match_operand:SI 3 "immediate_operand" "i"))
9020    (clobber (match_scratch:DI 4 "=&r"))
9021    (clobber (match_scratch:SI 5 "=X"))]
9022   "TARGET_STRING && ! TARGET_POWERPC64
9023    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9024   "lswi %4,%1,%2\;stswi %4,%0,%2"
9025   [(set_attr "type" "store")
9026    (set_attr "update" "yes")
9027    (set_attr "indexed" "yes")
9028    (set_attr "cell_micro" "always")
9029    (set_attr "length" "8")])
9031 ;; Move up to 4 bytes at a time.
9032 (define_expand "movmemsi_1reg"
9033   [(parallel [(set (match_operand 0 "" "")
9034                    (match_operand 1 "" ""))
9035               (use (match_operand 2 "" ""))
9036               (use (match_operand 3 "" ""))
9037               (clobber (match_scratch:SI 4 ""))
9038               (clobber (match_scratch:SI 5 ""))])]
9039   "TARGET_STRING"
9040   "")
9042 (define_insn ""
9043   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9044         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9045    (use (match_operand:SI 2 "immediate_operand" "i"))
9046    (use (match_operand:SI 3 "immediate_operand" "i"))
9047    (clobber (match_scratch:SI 4 "=&r"))
9048    (clobber (match_scratch:SI 5 "=X"))]
9049   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9050   "lswi %4,%1,%2\;stswi %4,%0,%2"
9051   [(set_attr "type" "store")
9052    (set_attr "update" "yes")
9053    (set_attr "indexed" "yes")
9054    (set_attr "cell_micro" "always")
9055    (set_attr "length" "8")])
9057 ;; Define insns that do load or store with update.  Some of these we can
9058 ;; get by using pre-decrement or pre-increment, but the hardware can also
9059 ;; do cases where the increment is not the size of the object.
9061 ;; In all these cases, we use operands 0 and 1 for the register being
9062 ;; incremented because those are the operands that local-alloc will
9063 ;; tie and these are the pair most likely to be tieable (and the ones
9064 ;; that will benefit the most).
9066 (define_insn "*movdi_update1"
9067   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9068         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9069                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9070    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9071         (plus:DI (match_dup 1) (match_dup 2)))]
9072   "TARGET_POWERPC64 && TARGET_UPDATE
9073    && (!avoiding_indexed_address_p (DImode)
9074        || !gpc_reg_operand (operands[2], DImode))"
9075   "@
9076    ldux %3,%0,%2
9077    ldu %3,%2(%0)"
9078   [(set_attr "type" "load")
9079    (set_attr "update" "yes")
9080    (set_attr "indexed" "yes,no")])
9082 (define_insn "movdi_<mode>_update"
9083   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9084                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9085         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9086    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9087         (plus:P (match_dup 1) (match_dup 2)))]
9088   "TARGET_POWERPC64 && TARGET_UPDATE
9089    && (!avoiding_indexed_address_p (Pmode)
9090        || !gpc_reg_operand (operands[2], Pmode)
9091        || (REG_P (operands[0])
9092            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9093   "@
9094    stdux %3,%0,%2
9095    stdu %3,%2(%0)"
9096   [(set_attr "type" "store")
9097    (set_attr "update" "yes")
9098    (set_attr "indexed" "yes,no")])
9100 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9101 ;; needed for stack allocation, even if the user passes -mno-update.
9102 (define_insn "movdi_<mode>_update_stack"
9103   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9104                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9105         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9106    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9107         (plus:P (match_dup 1) (match_dup 2)))]
9108   "TARGET_POWERPC64"
9109   "@
9110    stdux %3,%0,%2
9111    stdu %3,%2(%0)"
9112   [(set_attr "type" "store")
9113    (set_attr "update" "yes")
9114    (set_attr "indexed" "yes,no")])
9116 (define_insn "*movsi_update1"
9117   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9118         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9119                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9120    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9121         (plus:SI (match_dup 1) (match_dup 2)))]
9122   "TARGET_UPDATE
9123    && (!avoiding_indexed_address_p (SImode)
9124        || !gpc_reg_operand (operands[2], SImode))"
9125   "@
9126    lwzux %3,%0,%2
9127    lwzu %3,%2(%0)"
9128   [(set_attr "type" "load")
9129    (set_attr "update" "yes")
9130    (set_attr "indexed" "yes,no")])
9132 (define_insn "*movsi_update2"
9133   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9134         (sign_extend:DI
9135          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9136                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9137    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9138         (plus:DI (match_dup 1) (match_dup 2)))]
9139   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9140    && !avoiding_indexed_address_p (DImode)"
9141   "lwaux %3,%0,%2"
9142   [(set_attr "type" "load")
9143    (set_attr "sign_extend" "yes")
9144    (set_attr "update" "yes")
9145    (set_attr "indexed" "yes")])
9147 (define_insn "movsi_update"
9148   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9149                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9150         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9151    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9152         (plus:SI (match_dup 1) (match_dup 2)))]
9153   "TARGET_UPDATE
9154    && (!avoiding_indexed_address_p (SImode)
9155        || !gpc_reg_operand (operands[2], SImode)
9156        || (REG_P (operands[0])
9157            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9158   "@
9159    stwux %3,%0,%2
9160    stwu %3,%2(%0)"
9161   [(set_attr "type" "store")
9162    (set_attr "update" "yes")
9163    (set_attr "indexed" "yes,no")])
9165 ;; This is an unconditional pattern; needed for stack allocation, even
9166 ;; if the user passes -mno-update.
9167 (define_insn "movsi_update_stack"
9168   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9169                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9170         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9171    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9172         (plus:SI (match_dup 1) (match_dup 2)))]
9173   ""
9174   "@
9175    stwux %3,%0,%2
9176    stwu %3,%2(%0)"
9177   [(set_attr "type" "store")
9178    (set_attr "update" "yes")
9179    (set_attr "indexed" "yes,no")])
9181 (define_insn "*movhi_update1"
9182   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9183         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9184                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9185    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9186         (plus:SI (match_dup 1) (match_dup 2)))]
9187   "TARGET_UPDATE
9188    && (!avoiding_indexed_address_p (SImode)
9189        || !gpc_reg_operand (operands[2], SImode))"
9190   "@
9191    lhzux %3,%0,%2
9192    lhzu %3,%2(%0)"
9193   [(set_attr "type" "load")
9194    (set_attr "update" "yes")
9195    (set_attr "indexed" "yes,no")])
9197 (define_insn "*movhi_update2"
9198   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9199         (zero_extend:SI
9200          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9201                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9202    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9203         (plus:SI (match_dup 1) (match_dup 2)))]
9204   "TARGET_UPDATE
9205    && (!avoiding_indexed_address_p (SImode)
9206        || !gpc_reg_operand (operands[2], SImode))"
9207   "@
9208    lhzux %3,%0,%2
9209    lhzu %3,%2(%0)"
9210   [(set_attr "type" "load")
9211    (set_attr "update" "yes")
9212    (set_attr "indexed" "yes,no")])
9214 (define_insn "*movhi_update3"
9215   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9216         (sign_extend:SI
9217          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9218                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9219    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9220         (plus:SI (match_dup 1) (match_dup 2)))]
9221   "TARGET_UPDATE && rs6000_gen_cell_microcode
9222    && (!avoiding_indexed_address_p (SImode)
9223        || !gpc_reg_operand (operands[2], SImode))"
9224   "@
9225    lhaux %3,%0,%2
9226    lhau %3,%2(%0)"
9227   [(set_attr "type" "load")
9228    (set_attr "sign_extend" "yes")
9229    (set_attr "update" "yes")
9230    (set_attr "indexed" "yes,no")])
9232 (define_insn "*movhi_update4"
9233   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9234                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9235         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9236    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9237         (plus:SI (match_dup 1) (match_dup 2)))]
9238   "TARGET_UPDATE
9239    && (!avoiding_indexed_address_p (SImode)
9240        || !gpc_reg_operand (operands[2], SImode))"
9241   "@
9242    sthux %3,%0,%2
9243    sthu %3,%2(%0)"
9244   [(set_attr "type" "store")
9245    (set_attr "update" "yes")
9246    (set_attr "indexed" "yes,no")])
9248 (define_insn "*movqi_update1"
9249   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9250         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9251                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9252    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9253         (plus:SI (match_dup 1) (match_dup 2)))]
9254   "TARGET_UPDATE
9255    && (!avoiding_indexed_address_p (SImode)
9256        || !gpc_reg_operand (operands[2], SImode))"
9257   "@
9258    lbzux %3,%0,%2
9259    lbzu %3,%2(%0)"
9260   [(set_attr "type" "load")
9261    (set_attr "update" "yes")
9262    (set_attr "indexed" "yes,no")])
9264 (define_insn "*movqi_update2"
9265   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9266         (zero_extend:SI
9267          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9268                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9269    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9270         (plus:SI (match_dup 1) (match_dup 2)))]
9271   "TARGET_UPDATE
9272    && (!avoiding_indexed_address_p (SImode)
9273        || !gpc_reg_operand (operands[2], SImode))"
9274   "@
9275    lbzux %3,%0,%2
9276    lbzu %3,%2(%0)"
9277   [(set_attr "type" "load")
9278    (set_attr "update" "yes")
9279    (set_attr "indexed" "yes,no")])
9281 (define_insn "*movqi_update3"
9282   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9283                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9284         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9285    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9286         (plus:SI (match_dup 1) (match_dup 2)))]
9287   "TARGET_UPDATE
9288    && (!avoiding_indexed_address_p (SImode)
9289        || !gpc_reg_operand (operands[2], SImode))"
9290   "@
9291    stbux %3,%0,%2
9292    stbu %3,%2(%0)"
9293   [(set_attr "type" "store")
9294    (set_attr "update" "yes")
9295    (set_attr "indexed" "yes,no")])
9297 (define_insn "*movsf_update1"
9298   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9299         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9300                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9301    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9302         (plus:SI (match_dup 1) (match_dup 2)))]
9303   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9304    && (!avoiding_indexed_address_p (SImode)
9305        || !gpc_reg_operand (operands[2], SImode))"
9306   "@
9307    lfsux %3,%0,%2
9308    lfsu %3,%2(%0)"
9309   [(set_attr "type" "fpload")
9310    (set_attr "update" "yes")
9311    (set_attr "indexed" "yes,no")])
9313 (define_insn "*movsf_update2"
9314   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9315                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9316         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9317    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9318         (plus:SI (match_dup 1) (match_dup 2)))]
9319   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9320    && (!avoiding_indexed_address_p (SImode)
9321        || !gpc_reg_operand (operands[2], SImode))"
9322   "@
9323    stfsux %3,%0,%2
9324    stfsu %3,%2(%0)"
9325   [(set_attr "type" "fpstore")
9326    (set_attr "update" "yes")
9327    (set_attr "indexed" "yes,no")])
9329 (define_insn "*movsf_update3"
9330   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9331         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9332                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9333    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9334         (plus:SI (match_dup 1) (match_dup 2)))]
9335   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9336    && (!avoiding_indexed_address_p (SImode)
9337        || !gpc_reg_operand (operands[2], SImode))"
9338   "@
9339    lwzux %3,%0,%2
9340    lwzu %3,%2(%0)"
9341   [(set_attr "type" "load")
9342    (set_attr "update" "yes")
9343    (set_attr "indexed" "yes,no")])
9345 (define_insn "*movsf_update4"
9346   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9347                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9348         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9349    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9350         (plus:SI (match_dup 1) (match_dup 2)))]
9351   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9352    && (!avoiding_indexed_address_p (SImode)
9353        || !gpc_reg_operand (operands[2], SImode))"
9354   "@
9355    stwux %3,%0,%2
9356    stwu %3,%2(%0)"
9357   [(set_attr "type" "store")
9358    (set_attr "update" "yes")
9359    (set_attr "indexed" "yes,no")])
9361 (define_insn "*movdf_update1"
9362   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9363         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9364                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9365    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9366         (plus:SI (match_dup 1) (match_dup 2)))]
9367   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9368    && (!avoiding_indexed_address_p (SImode)
9369        || !gpc_reg_operand (operands[2], SImode))"
9370   "@
9371    lfdux %3,%0,%2
9372    lfdu %3,%2(%0)"
9373   [(set_attr "type" "fpload")
9374    (set_attr "update" "yes")
9375    (set_attr "indexed" "yes,no")
9376    (set_attr "size" "64")])
9378 (define_insn "*movdf_update2"
9379   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9380                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9381         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9382    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9383         (plus:SI (match_dup 1) (match_dup 2)))]
9384   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9385    && (!avoiding_indexed_address_p (SImode)
9386        || !gpc_reg_operand (operands[2], SImode))"
9387   "@
9388    stfdux %3,%0,%2
9389    stfdu %3,%2(%0)"
9390   [(set_attr "type" "fpstore")
9391    (set_attr "update" "yes")
9392    (set_attr "indexed" "yes,no")])
9395 ;; After inserting conditional returns we can sometimes have
9396 ;; unnecessary register moves.  Unfortunately we cannot have a
9397 ;; modeless peephole here, because some single SImode sets have early
9398 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9399 ;; sequences, using get_attr_length here will smash the operands
9400 ;; array.  Neither is there an early_cobbler_p predicate.
9401 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9402 ;; Also this optimization interferes with scalars going into
9403 ;; altivec registers (the code does reloading through the FPRs).
9404 (define_peephole2
9405   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9406         (match_operand:DF 1 "any_operand" ""))
9407    (set (match_operand:DF 2 "gpc_reg_operand" "")
9408         (match_dup 0))]
9409   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9410    && !TARGET_UPPER_REGS_DF
9411    && peep2_reg_dead_p (2, operands[0])"
9412   [(set (match_dup 2) (match_dup 1))])
9414 (define_peephole2
9415   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9416         (match_operand:SF 1 "any_operand" ""))
9417    (set (match_operand:SF 2 "gpc_reg_operand" "")
9418         (match_dup 0))]
9419   "!TARGET_UPPER_REGS_SF
9420    && peep2_reg_dead_p (2, operands[0])"
9421   [(set (match_dup 2) (match_dup 1))])
9424 ;; TLS support.
9426 ;; Mode attributes for different ABIs.
9427 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9428 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9429 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9430 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9432 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9433   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9434         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9435               (match_operand 4 "" "g")))
9436    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9437                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9438                    UNSPEC_TLSGD)
9439    (clobber (reg:SI LR_REGNO))]
9440   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9442   if (TARGET_CMODEL != CMODEL_SMALL)
9443     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9444            "bl %z3\;nop";
9445   else
9446     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9448   "&& TARGET_TLS_MARKERS"
9449   [(set (match_dup 0)
9450         (unspec:TLSmode [(match_dup 1)
9451                          (match_dup 2)]
9452                         UNSPEC_TLSGD))
9453    (parallel [(set (match_dup 0)
9454                    (call (mem:TLSmode (match_dup 3))
9455                          (match_dup 4)))
9456               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9457               (clobber (reg:SI LR_REGNO))])]
9458   ""
9459   [(set_attr "type" "two")
9460    (set (attr "length")
9461      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9462                    (const_int 16)
9463                    (const_int 12)))])
9465 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9466   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9467         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9468               (match_operand 4 "" "g")))
9469    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9470                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9471                    UNSPEC_TLSGD)
9472    (clobber (reg:SI LR_REGNO))]
9473   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9475   if (flag_pic)
9476     {
9477       if (TARGET_SECURE_PLT && flag_pic == 2)
9478         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9479       else
9480         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9481     }
9482   else
9483     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9485   "&& TARGET_TLS_MARKERS"
9486   [(set (match_dup 0)
9487         (unspec:TLSmode [(match_dup 1)
9488                          (match_dup 2)]
9489                         UNSPEC_TLSGD))
9490    (parallel [(set (match_dup 0)
9491                    (call (mem:TLSmode (match_dup 3))
9492                          (match_dup 4)))
9493               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9494               (clobber (reg:SI LR_REGNO))])]
9495   ""
9496   [(set_attr "type" "two")
9497    (set_attr "length" "8")])
9499 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9500   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9501         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9502                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9503                         UNSPEC_TLSGD))]
9504   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9505   "addi %0,%1,%2@got@tlsgd"
9506   "&& TARGET_CMODEL != CMODEL_SMALL"
9507   [(set (match_dup 3)
9508         (high:TLSmode
9509             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9510    (set (match_dup 0)
9511         (lo_sum:TLSmode (match_dup 3)
9512             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9513   "
9515   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9517   [(set (attr "length")
9518      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9519                    (const_int 8)
9520                    (const_int 4)))])
9522 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9523   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9524      (high:TLSmode
9525        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9526                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9527                        UNSPEC_TLSGD)))]
9528   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9529   "addis %0,%1,%2@got@tlsgd@ha"
9530   [(set_attr "length" "4")])
9532 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9533   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9535        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9536                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9537                        UNSPEC_TLSGD)))]
9538   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9539   "addi %0,%1,%2@got@tlsgd@l"
9540   [(set_attr "length" "4")])
9542 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9543   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9544         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9545               (match_operand 2 "" "g")))
9546    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9547                    UNSPEC_TLSGD)
9548    (clobber (reg:SI LR_REGNO))]
9549   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9550    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9551   "bl %z1(%3@tlsgd)\;nop"
9552   [(set_attr "type" "branch")
9553    (set_attr "length" "8")])
9555 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9556   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9557         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9558               (match_operand 2 "" "g")))
9559    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9560                    UNSPEC_TLSGD)
9561    (clobber (reg:SI LR_REGNO))]
9562   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9564   if (flag_pic)
9565     {
9566       if (TARGET_SECURE_PLT && flag_pic == 2)
9567         return "bl %z1+32768(%3@tlsgd)@plt";
9568       return "bl %z1(%3@tlsgd)@plt";
9569     }
9570   return "bl %z1(%3@tlsgd)";
9572   [(set_attr "type" "branch")
9573    (set_attr "length" "4")])
9575 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9576   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9577         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9578               (match_operand 3 "" "g")))
9579    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9580                    UNSPEC_TLSLD)
9581    (clobber (reg:SI LR_REGNO))]
9582   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9584   if (TARGET_CMODEL != CMODEL_SMALL)
9585     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9586            "bl %z2\;nop";
9587   else
9588     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9590   "&& TARGET_TLS_MARKERS"
9591   [(set (match_dup 0)
9592         (unspec:TLSmode [(match_dup 1)]
9593                         UNSPEC_TLSLD))
9594    (parallel [(set (match_dup 0)
9595                    (call (mem:TLSmode (match_dup 2))
9596                          (match_dup 3)))
9597               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9598               (clobber (reg:SI LR_REGNO))])]
9599   ""
9600   [(set_attr "type" "two")
9601    (set (attr "length")
9602      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9603                    (const_int 16)
9604                    (const_int 12)))])
9606 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9607   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9608         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9609               (match_operand 3 "" "g")))
9610    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9611                    UNSPEC_TLSLD)
9612    (clobber (reg:SI LR_REGNO))]
9613   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9615   if (flag_pic)
9616     {
9617       if (TARGET_SECURE_PLT && flag_pic == 2)
9618         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9619       else
9620         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9621     }
9622   else
9623     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9625   "&& TARGET_TLS_MARKERS"
9626   [(set (match_dup 0)
9627         (unspec:TLSmode [(match_dup 1)]
9628                         UNSPEC_TLSLD))
9629    (parallel [(set (match_dup 0)
9630                    (call (mem:TLSmode (match_dup 2))
9631                          (match_dup 3)))
9632               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9633               (clobber (reg:SI LR_REGNO))])]
9634   ""
9635   [(set_attr "length" "8")])
9637 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9638   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9639         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9640                         UNSPEC_TLSLD))]
9641   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9642   "addi %0,%1,%&@got@tlsld"
9643   "&& TARGET_CMODEL != CMODEL_SMALL"
9644   [(set (match_dup 2)
9645         (high:TLSmode
9646             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9647    (set (match_dup 0)
9648         (lo_sum:TLSmode (match_dup 2)
9649             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9650   "
9652   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9654   [(set (attr "length")
9655      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9656                    (const_int 8)
9657                    (const_int 4)))])
9659 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9660   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9661      (high:TLSmode
9662        (unspec:TLSmode [(const_int 0)
9663                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9664                        UNSPEC_TLSLD)))]
9665   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9666   "addis %0,%1,%&@got@tlsld@ha"
9667   [(set_attr "length" "4")])
9669 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9670   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9671      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9672        (unspec:TLSmode [(const_int 0)
9673                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9674                        UNSPEC_TLSLD)))]
9675   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9676   "addi %0,%1,%&@got@tlsld@l"
9677   [(set_attr "length" "4")])
9679 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9680   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9681         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9682               (match_operand 2 "" "g")))
9683    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9684    (clobber (reg:SI LR_REGNO))]
9685   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9686    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9687   "bl %z1(%&@tlsld)\;nop"
9688   [(set_attr "type" "branch")
9689    (set_attr "length" "8")])
9691 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9692   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9693         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9694               (match_operand 2 "" "g")))
9695    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9696    (clobber (reg:SI LR_REGNO))]
9697   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9699   if (flag_pic)
9700     {
9701       if (TARGET_SECURE_PLT && flag_pic == 2)
9702         return "bl %z1+32768(%&@tlsld)@plt";
9703       return "bl %z1(%&@tlsld)@plt";
9704     }
9705   return "bl %z1(%&@tlsld)";
9707   [(set_attr "type" "branch")
9708    (set_attr "length" "4")])
9710 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9711   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9712         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9713                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9714                         UNSPEC_TLSDTPREL))]
9715   "HAVE_AS_TLS"
9716   "addi %0,%1,%2@dtprel")
9718 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9719   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9720         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9721                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9722                         UNSPEC_TLSDTPRELHA))]
9723   "HAVE_AS_TLS"
9724   "addis %0,%1,%2@dtprel@ha")
9726 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9727   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9728         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9729                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9730                         UNSPEC_TLSDTPRELLO))]
9731   "HAVE_AS_TLS"
9732   "addi %0,%1,%2@dtprel@l")
9734 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9735   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9736         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9737                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9738                         UNSPEC_TLSGOTDTPREL))]
9739   "HAVE_AS_TLS"
9740   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9741   "&& TARGET_CMODEL != CMODEL_SMALL"
9742   [(set (match_dup 3)
9743         (high:TLSmode
9744             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9745    (set (match_dup 0)
9746         (lo_sum:TLSmode (match_dup 3)
9747             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9748   "
9750   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9752   [(set (attr "length")
9753      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9754                    (const_int 8)
9755                    (const_int 4)))])
9757 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9758   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9759      (high:TLSmode
9760        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9761                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9762                        UNSPEC_TLSGOTDTPREL)))]
9763   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9764   "addis %0,%1,%2@got@dtprel@ha"
9765   [(set_attr "length" "4")])
9767 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9768   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9769      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9770          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9771                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9772                          UNSPEC_TLSGOTDTPREL)))]
9773   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9774   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9775   [(set_attr "length" "4")])
9777 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9778   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9779         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9780                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9781                         UNSPEC_TLSTPREL))]
9782   "HAVE_AS_TLS"
9783   "addi %0,%1,%2@tprel")
9785 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9786   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9787         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9788                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9789                         UNSPEC_TLSTPRELHA))]
9790   "HAVE_AS_TLS"
9791   "addis %0,%1,%2@tprel@ha")
9793 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9794   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9795         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9796                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9797                         UNSPEC_TLSTPRELLO))]
9798   "HAVE_AS_TLS"
9799   "addi %0,%1,%2@tprel@l")
9801 ;; "b" output constraint here and on tls_tls input to support linker tls
9802 ;; optimization.  The linker may edit the instructions emitted by a
9803 ;; tls_got_tprel/tls_tls pair to addis,addi.
9804 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9805   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9806         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9807                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9808                         UNSPEC_TLSGOTTPREL))]
9809   "HAVE_AS_TLS"
9810   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9811   "&& TARGET_CMODEL != CMODEL_SMALL"
9812   [(set (match_dup 3)
9813         (high:TLSmode
9814             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9815    (set (match_dup 0)
9816         (lo_sum:TLSmode (match_dup 3)
9817             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9818   "
9820   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9822   [(set (attr "length")
9823      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9824                    (const_int 8)
9825                    (const_int 4)))])
9827 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9828   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9829      (high:TLSmode
9830        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9831                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9832                        UNSPEC_TLSGOTTPREL)))]
9833   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9834   "addis %0,%1,%2@got@tprel@ha"
9835   [(set_attr "length" "4")])
9837 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9838   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9839      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9840          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9841                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9842                          UNSPEC_TLSGOTTPREL)))]
9843   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9844   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9845   [(set_attr "length" "4")])
9847 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9848   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9849         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9850                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9851                         UNSPEC_TLSTLS))]
9852   "TARGET_ELF && HAVE_AS_TLS"
9853   "add %0,%1,%2@tls")
9855 (define_expand "tls_get_tpointer"
9856   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9857         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9858   "TARGET_XCOFF && HAVE_AS_TLS"
9859   "
9861   emit_insn (gen_tls_get_tpointer_internal ());
9862   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9863   DONE;
9866 (define_insn "tls_get_tpointer_internal"
9867   [(set (reg:SI 3)
9868         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9869    (clobber (reg:SI LR_REGNO))]
9870   "TARGET_XCOFF && HAVE_AS_TLS"
9871   "bla __get_tpointer")
9873 (define_expand "tls_get_addr<mode>"
9874   [(set (match_operand:P 0 "gpc_reg_operand" "")
9875         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9876                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9877   "TARGET_XCOFF && HAVE_AS_TLS"
9878   "
9880   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9881   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9882   emit_insn (gen_tls_get_addr_internal<mode> ());
9883   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9884   DONE;
9887 (define_insn "tls_get_addr_internal<mode>"
9888   [(set (reg:P 3)
9889         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9890    (clobber (reg:P 0))
9891    (clobber (reg:P 4))
9892    (clobber (reg:P 5))
9893    (clobber (reg:P 11))
9894    (clobber (reg:CC CR0_REGNO))
9895    (clobber (reg:P LR_REGNO))]
9896   "TARGET_XCOFF && HAVE_AS_TLS"
9897   "bla __tls_get_addr")
9899 ;; Next come insns related to the calling sequence.
9901 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9902 ;; We move the back-chain and decrement the stack pointer.
9904 (define_expand "allocate_stack"
9905   [(set (match_operand 0 "gpc_reg_operand" "")
9906         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9907    (set (reg 1)
9908         (minus (reg 1) (match_dup 1)))]
9909   ""
9910   "
9911 { rtx chain = gen_reg_rtx (Pmode);
9912   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9913   rtx neg_op0;
9914   rtx insn, par, set, mem;
9916   emit_move_insn (chain, stack_bot);
9918   /* Check stack bounds if necessary.  */
9919   if (crtl->limit_stack)
9920     {
9921       rtx available;
9922       available = expand_binop (Pmode, sub_optab,
9923                                 stack_pointer_rtx, stack_limit_rtx,
9924                                 NULL_RTX, 1, OPTAB_WIDEN);
9925       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9926     }
9928   if (GET_CODE (operands[1]) != CONST_INT
9929       || INTVAL (operands[1]) < -32767
9930       || INTVAL (operands[1]) > 32768)
9931     {
9932       neg_op0 = gen_reg_rtx (Pmode);
9933       if (TARGET_32BIT)
9934         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9935       else
9936         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9937     }
9938   else
9939     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9941   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9942                                        : gen_movdi_di_update_stack))
9943                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9944                          chain));
9945   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9946      it now and set the alias set/attributes. The above gen_*_update
9947      calls will generate a PARALLEL with the MEM set being the first
9948      operation. */
9949   par = PATTERN (insn);
9950   gcc_assert (GET_CODE (par) == PARALLEL);
9951   set = XVECEXP (par, 0, 0);
9952   gcc_assert (GET_CODE (set) == SET);
9953   mem = SET_DEST (set);
9954   gcc_assert (MEM_P (mem));
9955   MEM_NOTRAP_P (mem) = 1;
9956   set_mem_alias_set (mem, get_frame_alias_set ());
9958   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9959   DONE;
9962 ;; These patterns say how to save and restore the stack pointer.  We need not
9963 ;; save the stack pointer at function level since we are careful to
9964 ;; preserve the backchain.  At block level, we have to restore the backchain
9965 ;; when we restore the stack pointer.
9967 ;; For nonlocal gotos, we must save both the stack pointer and its
9968 ;; backchain and restore both.  Note that in the nonlocal case, the
9969 ;; save area is a memory location.
9971 (define_expand "save_stack_function"
9972   [(match_operand 0 "any_operand" "")
9973    (match_operand 1 "any_operand" "")]
9974   ""
9975   "DONE;")
9977 (define_expand "restore_stack_function"
9978   [(match_operand 0 "any_operand" "")
9979    (match_operand 1 "any_operand" "")]
9980   ""
9981   "DONE;")
9983 ;; Adjust stack pointer (op0) to a new value (op1).
9984 ;; First copy old stack backchain to new location, and ensure that the
9985 ;; scheduler won't reorder the sp assignment before the backchain write.
9986 (define_expand "restore_stack_block"
9987   [(set (match_dup 2) (match_dup 3))
9988    (set (match_dup 4) (match_dup 2))
9989    (match_dup 5)
9990    (set (match_operand 0 "register_operand" "")
9991         (match_operand 1 "register_operand" ""))]
9992   ""
9993   "
9995   rtvec p;
9997   operands[1] = force_reg (Pmode, operands[1]);
9998   operands[2] = gen_reg_rtx (Pmode);
9999   operands[3] = gen_frame_mem (Pmode, operands[0]);
10000   operands[4] = gen_frame_mem (Pmode, operands[1]);
10001   p = rtvec_alloc (1);
10002   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10003                                   const0_rtx);
10004   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10007 (define_expand "save_stack_nonlocal"
10008   [(set (match_dup 3) (match_dup 4))
10009    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10010    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10011   ""
10012   "
10014   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10016   /* Copy the backchain to the first word, sp to the second.  */
10017   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10018   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10019   operands[3] = gen_reg_rtx (Pmode);
10020   operands[4] = gen_frame_mem (Pmode, operands[1]);
10023 (define_expand "restore_stack_nonlocal"
10024   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10025    (set (match_dup 3) (match_dup 4))
10026    (set (match_dup 5) (match_dup 2))
10027    (match_dup 6)
10028    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10029   ""
10030   "
10032   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10033   rtvec p;
10035   /* Restore the backchain from the first word, sp from the second.  */
10036   operands[2] = gen_reg_rtx (Pmode);
10037   operands[3] = gen_reg_rtx (Pmode);
10038   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10039   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10040   operands[5] = gen_frame_mem (Pmode, operands[3]);
10041   p = rtvec_alloc (1);
10042   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10043                                   const0_rtx);
10044   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10047 ;; TOC register handling.
10049 ;; Code to initialize the TOC register...
10051 (define_insn "load_toc_aix_si"
10052   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10053                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10054               (use (reg:SI 2))])]
10055   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10056   "*
10058   char buf[30];
10059   extern int need_toc_init;
10060   need_toc_init = 1;
10061   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10062   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10063   operands[2] = gen_rtx_REG (Pmode, 2);
10064   return \"lwz %0,%1(%2)\";
10066   [(set_attr "type" "load")
10067    (set_attr "update" "no")
10068    (set_attr "indexed" "no")])
10070 (define_insn "load_toc_aix_di"
10071   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10072                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10073               (use (reg:DI 2))])]
10074   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10075   "*
10077   char buf[30];
10078   extern int need_toc_init;
10079   need_toc_init = 1;
10080   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10081                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10082   if (TARGET_ELF)
10083     strcat (buf, \"@toc\");
10084   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10085   operands[2] = gen_rtx_REG (Pmode, 2);
10086   return \"ld %0,%1(%2)\";
10088   [(set_attr "type" "load")
10089    (set_attr "update" "no")
10090    (set_attr "indexed" "no")])
10092 (define_insn "load_toc_v4_pic_si"
10093   [(set (reg:SI LR_REGNO)
10094         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10095   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10096   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10097   [(set_attr "type" "branch")
10098    (set_attr "length" "4")])
10100 (define_expand "load_toc_v4_PIC_1"
10101   [(parallel [(set (reg:SI LR_REGNO)
10102                    (match_operand:SI 0 "immediate_operand" "s"))
10103               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10104   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10105    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10106   "")
10108 (define_insn "load_toc_v4_PIC_1_normal"
10109   [(set (reg:SI LR_REGNO)
10110         (match_operand:SI 0 "immediate_operand" "s"))
10111    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10112   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10113    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10114   "bcl 20,31,%0\\n%0:"
10115   [(set_attr "type" "branch")
10116    (set_attr "length" "4")
10117    (set_attr "cannot_copy" "yes")])
10119 (define_insn "load_toc_v4_PIC_1_476"
10120   [(set (reg:SI LR_REGNO)
10121         (match_operand:SI 0 "immediate_operand" "s"))
10122    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10123   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10124    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10125   "*
10127   char name[32];
10128   static char templ[32];
10130   get_ppc476_thunk_name (name);
10131   sprintf (templ, \"bl %s\\n%%0:\", name);
10132   return templ;
10134   [(set_attr "type" "branch")
10135    (set_attr "length" "4")
10136    (set_attr "cannot_copy" "yes")])
10138 (define_expand "load_toc_v4_PIC_1b"
10139   [(parallel [(set (reg:SI LR_REGNO)
10140                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10141                                (label_ref (match_operand 1 "" ""))]
10142                            UNSPEC_TOCPTR))
10143               (match_dup 1)])]
10144   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10145   "")
10147 (define_insn "load_toc_v4_PIC_1b_normal"
10148   [(set (reg:SI LR_REGNO)
10149         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10150                     (label_ref (match_operand 1 "" ""))]
10151                 UNSPEC_TOCPTR))
10152    (match_dup 1)]
10153   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10154   "bcl 20,31,$+8\;.long %0-$"
10155   [(set_attr "type" "branch")
10156    (set_attr "length" "8")])
10158 (define_insn "load_toc_v4_PIC_1b_476"
10159   [(set (reg:SI LR_REGNO)
10160         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10161                     (label_ref (match_operand 1 "" ""))]
10162                 UNSPEC_TOCPTR))
10163    (match_dup 1)]
10164   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10165   "*
10167   char name[32];
10168   static char templ[32];
10170   get_ppc476_thunk_name (name);
10171   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10172   return templ;
10174   [(set_attr "type" "branch")
10175    (set_attr "length" "16")])
10177 (define_insn "load_toc_v4_PIC_2"
10178   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10179         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10180                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10181                              (match_operand:SI 3 "immediate_operand" "s")))))]
10182   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10183   "lwz %0,%2-%3(%1)"
10184   [(set_attr "type" "load")])
10186 (define_insn "load_toc_v4_PIC_3b"
10187   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10188         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10189                  (high:SI
10190                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10191                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10192   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10193   "addis %0,%1,%2-%3@ha")
10195 (define_insn "load_toc_v4_PIC_3c"
10196   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10197         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10198                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10199                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10200   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10201   "addi %0,%1,%2-%3@l")
10203 ;; If the TOC is shared over a translation unit, as happens with all
10204 ;; the kinds of PIC that we support, we need to restore the TOC
10205 ;; pointer only when jumping over units of translation.
10206 ;; On Darwin, we need to reload the picbase.
10208 (define_expand "builtin_setjmp_receiver"
10209   [(use (label_ref (match_operand 0 "" "")))]
10210   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10211    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10212    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10213   "
10215 #if TARGET_MACHO
10216   if (DEFAULT_ABI == ABI_DARWIN)
10217     {
10218       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10219       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10220       rtx tmplabrtx;
10221       char tmplab[20];
10223       crtl->uses_pic_offset_table = 1;
10224       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10225                                   CODE_LABEL_NUMBER (operands[0]));
10226       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10228       emit_insn (gen_load_macho_picbase (tmplabrtx));
10229       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10230       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10231     }
10232   else
10233 #endif
10234     rs6000_emit_load_toc_table (FALSE);
10235   DONE;
10238 ;; Largetoc support
10239 (define_insn "*largetoc_high"
10240   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10241         (high:DI
10242           (unspec [(match_operand:DI 1 "" "")
10243                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10244                   UNSPEC_TOCREL)))]
10245    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10246    "addis %0,%2,%1@toc@ha")
10248 (define_insn "*largetoc_high_aix<mode>"
10249   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10250         (high:P
10251           (unspec [(match_operand:P 1 "" "")
10252                    (match_operand:P 2 "gpc_reg_operand" "b")]
10253                   UNSPEC_TOCREL)))]
10254    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10255    "addis %0,%1@u(%2)")
10257 (define_insn "*largetoc_high_plus"
10258   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10259         (high:DI
10260           (plus:DI
10261             (unspec [(match_operand:DI 1 "" "")
10262                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10263                     UNSPEC_TOCREL)
10264             (match_operand:DI 3 "add_cint_operand" "n"))))]
10265    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10266    "addis %0,%2,%1+%3@toc@ha")
10268 (define_insn "*largetoc_high_plus_aix<mode>"
10269   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10270         (high:P
10271           (plus:P
10272             (unspec [(match_operand:P 1 "" "")
10273                      (match_operand:P 2 "gpc_reg_operand" "b")]
10274                     UNSPEC_TOCREL)
10275             (match_operand:P 3 "add_cint_operand" "n"))))]
10276    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10277    "addis %0,%1+%3@u(%2)")
10279 (define_insn "*largetoc_low"
10280   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10281         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10282                    (match_operand:DI 2 "" "")))]
10283    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10284    "addi %0,%1,%2@l")
10286 (define_insn "*largetoc_low_aix<mode>"
10287   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10288         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10289                    (match_operand:P 2 "" "")))]
10290    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10291    "la %0,%2@l(%1)")
10293 (define_insn_and_split "*tocref<mode>"
10294   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10295         (match_operand:P 1 "small_toc_ref" "R"))]
10296    "TARGET_TOC"
10297    "la %0,%a1"
10298    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10299   [(set (match_dup 0) (high:P (match_dup 1)))
10300    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10302 ;; Elf specific ways of loading addresses for non-PIC code.
10303 ;; The output of this could be r0, but we make a very strong
10304 ;; preference for a base register because it will usually
10305 ;; be needed there.
10306 (define_insn "elf_high"
10307   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10308         (high:SI (match_operand 1 "" "")))]
10309   "TARGET_ELF && ! TARGET_64BIT"
10310   "lis %0,%1@ha")
10312 (define_insn "elf_low"
10313   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10314         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10315                    (match_operand 2 "" "")))]
10316    "TARGET_ELF && ! TARGET_64BIT"
10317    "la %0,%2@l(%1)")
10319 ;; Call and call_value insns
10320 (define_expand "call"
10321   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10322                     (match_operand 1 "" ""))
10323               (use (match_operand 2 "" ""))
10324               (clobber (reg:SI LR_REGNO))])]
10325   ""
10326   "
10328 #if TARGET_MACHO
10329   if (MACHOPIC_INDIRECT)
10330     operands[0] = machopic_indirect_call_target (operands[0]);
10331 #endif
10333   gcc_assert (GET_CODE (operands[0]) == MEM);
10334   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10336   operands[0] = XEXP (operands[0], 0);
10338   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10339     {
10340       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10341       DONE;
10342     }
10344   if (GET_CODE (operands[0]) != SYMBOL_REF
10345       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10346     {
10347       if (INTVAL (operands[2]) & CALL_LONG)
10348         operands[0] = rs6000_longcall_ref (operands[0]);
10350       switch (DEFAULT_ABI)
10351         {
10352         case ABI_V4:
10353         case ABI_DARWIN:
10354           operands[0] = force_reg (Pmode, operands[0]);
10355           break;
10357         default:
10358           gcc_unreachable ();
10359         }
10360     }
10363 (define_expand "call_value"
10364   [(parallel [(set (match_operand 0 "" "")
10365                    (call (mem:SI (match_operand 1 "address_operand" ""))
10366                          (match_operand 2 "" "")))
10367               (use (match_operand 3 "" ""))
10368               (clobber (reg:SI LR_REGNO))])]
10369   ""
10370   "
10372 #if TARGET_MACHO
10373   if (MACHOPIC_INDIRECT)
10374     operands[1] = machopic_indirect_call_target (operands[1]);
10375 #endif
10377   gcc_assert (GET_CODE (operands[1]) == MEM);
10378   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10380   operands[1] = XEXP (operands[1], 0);
10382   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10383     {
10384       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10385       DONE;
10386     }
10388   if (GET_CODE (operands[1]) != SYMBOL_REF
10389       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10390     {
10391       if (INTVAL (operands[3]) & CALL_LONG)
10392         operands[1] = rs6000_longcall_ref (operands[1]);
10394       switch (DEFAULT_ABI)
10395         {
10396         case ABI_V4:
10397         case ABI_DARWIN:
10398           operands[1] = force_reg (Pmode, operands[1]);
10399           break;
10401         default:
10402           gcc_unreachable ();
10403         }
10404     }
10407 ;; Call to function in current module.  No TOC pointer reload needed.
10408 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10409 ;; either the function was not prototyped, or it was prototyped as a
10410 ;; variable argument function.  It is > 0 if FP registers were passed
10411 ;; and < 0 if they were not.
10413 (define_insn "*call_local32"
10414   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10415          (match_operand 1 "" "g,g"))
10416    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10417    (clobber (reg:SI LR_REGNO))]
10418   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10419   "*
10421   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10422     output_asm_insn (\"crxor 6,6,6\", operands);
10424   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10425     output_asm_insn (\"creqv 6,6,6\", operands);
10427   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10429   [(set_attr "type" "branch")
10430    (set_attr "length" "4,8")])
10432 (define_insn "*call_local64"
10433   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10434          (match_operand 1 "" "g,g"))
10435    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10436    (clobber (reg:SI LR_REGNO))]
10437   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10438   "*
10440   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10441     output_asm_insn (\"crxor 6,6,6\", operands);
10443   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10444     output_asm_insn (\"creqv 6,6,6\", operands);
10446   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10448   [(set_attr "type" "branch")
10449    (set_attr "length" "4,8")])
10451 (define_insn "*call_value_local32"
10452   [(set (match_operand 0 "" "")
10453         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10454               (match_operand 2 "" "g,g")))
10455    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10456    (clobber (reg:SI LR_REGNO))]
10457   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10458   "*
10460   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10461     output_asm_insn (\"crxor 6,6,6\", operands);
10463   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10464     output_asm_insn (\"creqv 6,6,6\", operands);
10466   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10468   [(set_attr "type" "branch")
10469    (set_attr "length" "4,8")])
10472 (define_insn "*call_value_local64"
10473   [(set (match_operand 0 "" "")
10474         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10475               (match_operand 2 "" "g,g")))
10476    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10477    (clobber (reg:SI LR_REGNO))]
10478   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10479   "*
10481   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10482     output_asm_insn (\"crxor 6,6,6\", operands);
10484   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10485     output_asm_insn (\"creqv 6,6,6\", operands);
10487   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10489   [(set_attr "type" "branch")
10490    (set_attr "length" "4,8")])
10493 ;; A function pointer under System V is just a normal pointer
10494 ;; operands[0] is the function pointer
10495 ;; operands[1] is the stack size to clean up
10496 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10497 ;; which indicates how to set cr1
10499 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10500   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10501          (match_operand 1 "" "g,g,g,g"))
10502    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10503    (clobber (reg:SI LR_REGNO))]
10504   "DEFAULT_ABI == ABI_V4
10505    || DEFAULT_ABI == ABI_DARWIN"
10507   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10508     output_asm_insn ("crxor 6,6,6", operands);
10510   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10511     output_asm_insn ("creqv 6,6,6", operands);
10513   return "b%T0l";
10515   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10516    (set_attr "length" "4,4,8,8")])
10518 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10519   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10520          (match_operand 1 "" "g,g"))
10521    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10522    (clobber (reg:SI LR_REGNO))]
10523   "(DEFAULT_ABI == ABI_DARWIN
10524    || (DEFAULT_ABI == ABI_V4
10525        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10527   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10528     output_asm_insn ("crxor 6,6,6", operands);
10530   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10531     output_asm_insn ("creqv 6,6,6", operands);
10533 #if TARGET_MACHO
10534   return output_call(insn, operands, 0, 2);
10535 #else
10536   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10537     {
10538       gcc_assert (!TARGET_SECURE_PLT);
10539       return "bl %z0@plt";
10540     }
10541   else
10542     return "bl %z0";
10543 #endif
10545   "DEFAULT_ABI == ABI_V4
10546    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10547    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10548   [(parallel [(call (mem:SI (match_dup 0))
10549                     (match_dup 1))
10550               (use (match_dup 2))
10551               (use (match_dup 3))
10552               (clobber (reg:SI LR_REGNO))])]
10554   operands[3] = pic_offset_table_rtx;
10556   [(set_attr "type" "branch,branch")
10557    (set_attr "length" "4,8")])
10559 (define_insn "*call_nonlocal_sysv_secure<mode>"
10560   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10561          (match_operand 1 "" "g,g"))
10562    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10563    (use (match_operand:SI 3 "register_operand" "r,r"))
10564    (clobber (reg:SI LR_REGNO))]
10565   "(DEFAULT_ABI == ABI_V4
10566     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10567     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10569   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10570     output_asm_insn ("crxor 6,6,6", operands);
10572   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10573     output_asm_insn ("creqv 6,6,6", operands);
10575   if (flag_pic == 2)
10576     /* The magic 32768 offset here and in the other sysv call insns
10577        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10578        See sysv4.h:toc_section.  */
10579     return "bl %z0+32768@plt";
10580   else
10581     return "bl %z0@plt";
10583   [(set_attr "type" "branch,branch")
10584    (set_attr "length" "4,8")])
10586 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10587   [(set (match_operand 0 "" "")
10588         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10589               (match_operand 2 "" "g,g,g,g")))
10590    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10591    (clobber (reg:SI LR_REGNO))]
10592   "DEFAULT_ABI == ABI_V4
10593    || DEFAULT_ABI == ABI_DARWIN"
10595   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10596     output_asm_insn ("crxor 6,6,6", operands);
10598   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10599     output_asm_insn ("creqv 6,6,6", operands);
10601   return "b%T1l";
10603   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10604    (set_attr "length" "4,4,8,8")])
10606 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10607   [(set (match_operand 0 "" "")
10608         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10609               (match_operand 2 "" "g,g")))
10610    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10611    (clobber (reg:SI LR_REGNO))]
10612   "(DEFAULT_ABI == ABI_DARWIN
10613    || (DEFAULT_ABI == ABI_V4
10614        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10616   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10617     output_asm_insn ("crxor 6,6,6", operands);
10619   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10620     output_asm_insn ("creqv 6,6,6", operands);
10622 #if TARGET_MACHO
10623   return output_call(insn, operands, 1, 3);
10624 #else
10625   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10626     {
10627       gcc_assert (!TARGET_SECURE_PLT);
10628       return "bl %z1@plt";
10629     }
10630   else
10631     return "bl %z1";
10632 #endif
10634   "DEFAULT_ABI == ABI_V4
10635    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10636    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10637   [(parallel [(set (match_dup 0)
10638                    (call (mem:SI (match_dup 1))
10639                          (match_dup 2)))
10640               (use (match_dup 3))
10641               (use (match_dup 4))
10642               (clobber (reg:SI LR_REGNO))])]
10644   operands[4] = pic_offset_table_rtx;
10646   [(set_attr "type" "branch,branch")
10647    (set_attr "length" "4,8")])
10649 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10650   [(set (match_operand 0 "" "")
10651         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10652               (match_operand 2 "" "g,g")))
10653    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10654    (use (match_operand:SI 4 "register_operand" "r,r"))
10655    (clobber (reg:SI LR_REGNO))]
10656   "(DEFAULT_ABI == ABI_V4
10657     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10658     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10660   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10661     output_asm_insn ("crxor 6,6,6", operands);
10663   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10664     output_asm_insn ("creqv 6,6,6", operands);
10666   if (flag_pic == 2)
10667     return "bl %z1+32768@plt";
10668   else
10669     return "bl %z1@plt";
10671   [(set_attr "type" "branch,branch")
10672    (set_attr "length" "4,8")])
10675 ;; Call to AIX abi function in the same module.
10677 (define_insn "*call_local_aix<mode>"
10678   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10679          (match_operand 1 "" "g"))
10680    (clobber (reg:P LR_REGNO))]
10681   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10682   "bl %z0"
10683   [(set_attr "type" "branch")
10684    (set_attr "length" "4")])
10686 (define_insn "*call_value_local_aix<mode>"
10687   [(set (match_operand 0 "" "")
10688         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10689               (match_operand 2 "" "g")))
10690    (clobber (reg:P LR_REGNO))]
10691   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10692   "bl %z1"
10693   [(set_attr "type" "branch")
10694    (set_attr "length" "4")])
10696 ;; Call to AIX abi function which may be in another module.
10697 ;; Restore the TOC pointer (r2) after the call.
10699 (define_insn "*call_nonlocal_aix<mode>"
10700   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10701          (match_operand 1 "" "g"))
10702    (clobber (reg:P LR_REGNO))]
10703   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10704   "bl %z0\;nop"
10705   [(set_attr "type" "branch")
10706    (set_attr "length" "8")])
10708 (define_insn "*call_value_nonlocal_aix<mode>"
10709   [(set (match_operand 0 "" "")
10710         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10711               (match_operand 2 "" "g")))
10712    (clobber (reg:P LR_REGNO))]
10713   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10714   "bl %z1\;nop"
10715   [(set_attr "type" "branch")
10716    (set_attr "length" "8")])
10718 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10719 ;; Operand0 is the addresss of the function to call
10720 ;; Operand2 is the location in the function descriptor to load r2 from
10721 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10723 (define_insn "*call_indirect_aix<mode>"
10724   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10725          (match_operand 1 "" "g,g"))
10726    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10727    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10728    (clobber (reg:P LR_REGNO))]
10729   "DEFAULT_ABI == ABI_AIX"
10730   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10731   [(set_attr "type" "jmpreg")
10732    (set_attr "length" "12")])
10734 (define_insn "*call_value_indirect_aix<mode>"
10735   [(set (match_operand 0 "" "")
10736         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10737               (match_operand 2 "" "g,g")))
10738    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10739    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10740    (clobber (reg:P LR_REGNO))]
10741   "DEFAULT_ABI == ABI_AIX"
10742   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10743   [(set_attr "type" "jmpreg")
10744    (set_attr "length" "12")])
10746 ;; Call to indirect functions with the ELFv2 ABI.
10747 ;; Operand0 is the addresss of the function to call
10748 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10750 (define_insn "*call_indirect_elfv2<mode>"
10751   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10752          (match_operand 1 "" "g,g"))
10753    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10754    (clobber (reg:P LR_REGNO))]
10755   "DEFAULT_ABI == ABI_ELFv2"
10756   "b%T0l\;<ptrload> 2,%2(1)"
10757   [(set_attr "type" "jmpreg")
10758    (set_attr "length" "8")])
10760 (define_insn "*call_value_indirect_elfv2<mode>"
10761   [(set (match_operand 0 "" "")
10762         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10763               (match_operand 2 "" "g,g")))
10764    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10765    (clobber (reg:P LR_REGNO))]
10766   "DEFAULT_ABI == ABI_ELFv2"
10767   "b%T1l\;<ptrload> 2,%3(1)"
10768   [(set_attr "type" "jmpreg")
10769    (set_attr "length" "8")])
10772 ;; Call subroutine returning any type.
10773 (define_expand "untyped_call"
10774   [(parallel [(call (match_operand 0 "" "")
10775                     (const_int 0))
10776               (match_operand 1 "" "")
10777               (match_operand 2 "" "")])]
10778   ""
10779   "
10781   int i;
10783   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10785   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10786     {
10787       rtx set = XVECEXP (operands[2], 0, i);
10788       emit_move_insn (SET_DEST (set), SET_SRC (set));
10789     }
10791   /* The optimizer does not know that the call sets the function value
10792      registers we stored in the result block.  We avoid problems by
10793      claiming that all hard registers are used and clobbered at this
10794      point.  */
10795   emit_insn (gen_blockage ());
10797   DONE;
10800 ;; sibling call patterns
10801 (define_expand "sibcall"
10802   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10803                     (match_operand 1 "" ""))
10804               (use (match_operand 2 "" ""))
10805               (simple_return)])]
10806   ""
10807   "
10809 #if TARGET_MACHO
10810   if (MACHOPIC_INDIRECT)
10811     operands[0] = machopic_indirect_call_target (operands[0]);
10812 #endif
10814   gcc_assert (GET_CODE (operands[0]) == MEM);
10815   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10817   operands[0] = XEXP (operands[0], 0);
10819   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10820     {
10821       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10822       DONE;
10823     }
10826 (define_expand "sibcall_value"
10827   [(parallel [(set (match_operand 0 "register_operand" "")
10828                 (call (mem:SI (match_operand 1 "address_operand" ""))
10829                       (match_operand 2 "" "")))
10830               (use (match_operand 3 "" ""))
10831               (simple_return)])]
10832   ""
10833   "
10835 #if TARGET_MACHO
10836   if (MACHOPIC_INDIRECT)
10837     operands[1] = machopic_indirect_call_target (operands[1]);
10838 #endif
10840   gcc_assert (GET_CODE (operands[1]) == MEM);
10841   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10843   operands[1] = XEXP (operands[1], 0);
10845   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10846     {
10847       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10848       DONE;
10849     }
10852 (define_insn "*sibcall_local32"
10853   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10854          (match_operand 1 "" "g,g"))
10855    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10856    (simple_return)]
10857   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10858   "*
10860   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10861     output_asm_insn (\"crxor 6,6,6\", operands);
10863   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10864     output_asm_insn (\"creqv 6,6,6\", operands);
10866   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10868   [(set_attr "type" "branch")
10869    (set_attr "length" "4,8")])
10871 (define_insn "*sibcall_local64"
10872   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10873          (match_operand 1 "" "g,g"))
10874    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10875    (simple_return)]
10876   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10877   "*
10879   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10880     output_asm_insn (\"crxor 6,6,6\", operands);
10882   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10883     output_asm_insn (\"creqv 6,6,6\", operands);
10885   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10887   [(set_attr "type" "branch")
10888    (set_attr "length" "4,8")])
10890 (define_insn "*sibcall_value_local32"
10891   [(set (match_operand 0 "" "")
10892         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10893               (match_operand 2 "" "g,g")))
10894    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10895    (simple_return)]
10896   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10897   "*
10899   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10900     output_asm_insn (\"crxor 6,6,6\", operands);
10902   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10903     output_asm_insn (\"creqv 6,6,6\", operands);
10905   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10907   [(set_attr "type" "branch")
10908    (set_attr "length" "4,8")])
10910 (define_insn "*sibcall_value_local64"
10911   [(set (match_operand 0 "" "")
10912         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10913               (match_operand 2 "" "g,g")))
10914    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10915    (simple_return)]
10916   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10917   "*
10919   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10920     output_asm_insn (\"crxor 6,6,6\", operands);
10922   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10923     output_asm_insn (\"creqv 6,6,6\", operands);
10925   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10927   [(set_attr "type" "branch")
10928    (set_attr "length" "4,8")])
10930 (define_insn "*sibcall_nonlocal_sysv<mode>"
10931   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10932          (match_operand 1 "" ""))
10933    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10934    (simple_return)]
10935   "(DEFAULT_ABI == ABI_DARWIN
10936     || DEFAULT_ABI == ABI_V4)
10937    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10938   "*
10940   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10941     output_asm_insn (\"crxor 6,6,6\", operands);
10943   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10944     output_asm_insn (\"creqv 6,6,6\", operands);
10946   if (which_alternative >= 2)
10947     return \"b%T0\";
10948   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10949     {
10950       gcc_assert (!TARGET_SECURE_PLT);
10951       return \"b %z0@plt\";
10952     }
10953   else
10954     return \"b %z0\";
10956   [(set_attr "type" "branch")
10957    (set_attr "length" "4,8,4,8")])
10959 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10960   [(set (match_operand 0 "" "")
10961         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10962               (match_operand 2 "" "")))
10963    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10964    (simple_return)]
10965   "(DEFAULT_ABI == ABI_DARWIN
10966     || DEFAULT_ABI == ABI_V4)
10967    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10968   "*
10970   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10971     output_asm_insn (\"crxor 6,6,6\", operands);
10973   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10974     output_asm_insn (\"creqv 6,6,6\", operands);
10976   if (which_alternative >= 2)
10977     return \"b%T1\";
10978   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10979     {
10980       gcc_assert (!TARGET_SECURE_PLT);
10981       return \"b %z1@plt\";
10982     }
10983   else
10984     return \"b %z1\";
10986   [(set_attr "type" "branch")
10987    (set_attr "length" "4,8,4,8")])
10989 ;; AIX ABI sibling call patterns.
10991 (define_insn "*sibcall_aix<mode>"
10992   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10993          (match_operand 1 "" "g,g"))
10994    (simple_return)]
10995   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10996   "@
10997    b %z0
10998    b%T0"
10999   [(set_attr "type" "branch")
11000    (set_attr "length" "4")])
11002 (define_insn "*sibcall_value_aix<mode>"
11003   [(set (match_operand 0 "" "")
11004         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11005               (match_operand 2 "" "g,g")))
11006    (simple_return)]
11007   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11008   "@
11009    b %z1
11010    b%T1"
11011   [(set_attr "type" "branch")
11012    (set_attr "length" "4")])
11014 (define_expand "sibcall_epilogue"
11015   [(use (const_int 0))]
11016   ""
11018   if (!TARGET_SCHED_PROLOG)
11019     emit_insn (gen_blockage ());
11020   rs6000_emit_epilogue (TRUE);
11021   DONE;
11024 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11025 ;; all of memory.  This blocks insns from being moved across this point.
11027 (define_insn "blockage"
11028   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11029   ""
11030   "")
11032 (define_expand "probe_stack_address"
11033   [(use (match_operand 0 "address_operand"))]
11034   ""
11036   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11037   MEM_VOLATILE_P (operands[0]) = 1;
11039   if (TARGET_64BIT)
11040     emit_insn (gen_probe_stack_di (operands[0]));
11041   else
11042     emit_insn (gen_probe_stack_si (operands[0]));
11043   DONE;
11046 (define_insn "probe_stack_<mode>"
11047   [(set (match_operand:P 0 "memory_operand" "=m")
11048         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11049   ""
11051   operands[1] = gen_rtx_REG (Pmode, 0);
11052   return "st<wd>%U0%X0 %1,%0";
11054   [(set_attr "type" "store")
11055    (set (attr "update")
11056         (if_then_else (match_operand 0 "update_address_mem")
11057                       (const_string "yes")
11058                       (const_string "no")))
11059    (set (attr "indexed")
11060         (if_then_else (match_operand 0 "indexed_address_mem")
11061                       (const_string "yes")
11062                       (const_string "no")))
11063    (set_attr "length" "4")])
11065 (define_insn "probe_stack_range<P:mode>"
11066   [(set (match_operand:P 0 "register_operand" "=r")
11067         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11068                             (match_operand:P 2 "register_operand" "r")]
11069                            UNSPECV_PROBE_STACK_RANGE))]
11070   ""
11071   "* return output_probe_stack_range (operands[0], operands[2]);"
11072   [(set_attr "type" "three")])
11074 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11075 ;; signed & unsigned, and one type of branch.
11077 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11078 ;; insns, and branches.
11080 (define_expand "cbranch<mode>4"
11081   [(use (match_operator 0 "rs6000_cbranch_operator"
11082          [(match_operand:GPR 1 "gpc_reg_operand" "")
11083           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11084    (use (match_operand 3 ""))]
11085   ""
11086   "
11088   /* Take care of the possibility that operands[2] might be negative but
11089      this might be a logical operation.  That insn doesn't exist.  */
11090   if (GET_CODE (operands[2]) == CONST_INT
11091       && INTVAL (operands[2]) < 0)
11092     {
11093       operands[2] = force_reg (<MODE>mode, operands[2]);
11094       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11095                                     GET_MODE (operands[0]),
11096                                     operands[1], operands[2]);
11097    }
11099   rs6000_emit_cbranch (<MODE>mode, operands);
11100   DONE;
11103 (define_expand "cbranch<mode>4"
11104   [(use (match_operator 0 "rs6000_cbranch_operator"
11105          [(match_operand:FP 1 "gpc_reg_operand" "")
11106           (match_operand:FP 2 "gpc_reg_operand" "")]))
11107    (use (match_operand 3 ""))]
11108   ""
11109   "
11111   rs6000_emit_cbranch (<MODE>mode, operands);
11112   DONE;
11115 (define_expand "cstore<mode>4_signed"
11116   [(use (match_operator 1 "signed_comparison_operator"
11117          [(match_operand:P 2 "gpc_reg_operand")
11118           (match_operand:P 3 "gpc_reg_operand")]))
11119    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11120   ""
11122   enum rtx_code cond_code = GET_CODE (operands[1]);
11124   rtx op0 = operands[0];
11125   rtx op1 = operands[2];
11126   rtx op2 = operands[3];
11128   if (cond_code == GE || cond_code == LT)
11129     {
11130       cond_code = swap_condition (cond_code);
11131       std::swap (op1, op2);
11132     }
11134   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11135   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11136   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11138   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11139   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11140   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11142   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11144   if (cond_code == LE)
11145     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11146   else
11147     {
11148       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11149       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11150       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11151     }
11153   DONE;
11156 (define_expand "cstore<mode>4_unsigned"
11157   [(use (match_operator 1 "unsigned_comparison_operator"
11158          [(match_operand:P 2 "gpc_reg_operand")
11159           (match_operand:P 3 "reg_or_short_operand")]))
11160    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11161   ""
11163   enum rtx_code cond_code = GET_CODE (operands[1]);
11165   rtx op0 = operands[0];
11166   rtx op1 = operands[2];
11167   rtx op2 = operands[3];
11169   if (cond_code == GEU || cond_code == LTU)
11170     {
11171       cond_code = swap_condition (cond_code);
11172       std::swap (op1, op2);
11173     }
11175   if (!gpc_reg_operand (op1, <MODE>mode))
11176     op1 = force_reg (<MODE>mode, op1);
11177   if (!reg_or_short_operand (op2, <MODE>mode))
11178     op2 = force_reg (<MODE>mode, op2);
11180   rtx tmp = gen_reg_rtx (<MODE>mode);
11181   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11183   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11184   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11186   if (cond_code == LEU)
11187     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11188   else
11189     emit_insn (gen_neg<mode>2 (op0, tmp2));
11191   DONE;
11194 (define_expand "cstore_si_as_di"
11195   [(use (match_operator 1 "unsigned_comparison_operator"
11196          [(match_operand:SI 2 "gpc_reg_operand")
11197           (match_operand:SI 3 "reg_or_short_operand")]))
11198    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11199   ""
11201   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11202   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11204   operands[2] = force_reg (SImode, operands[2]);
11205   operands[3] = force_reg (SImode, operands[3]);
11206   rtx op1 = gen_reg_rtx (DImode);
11207   rtx op2 = gen_reg_rtx (DImode);
11208   convert_move (op1, operands[2], uns_flag);
11209   convert_move (op2, operands[3], uns_flag);
11211   if (cond_code == GT || cond_code == LE)
11212     {
11213       cond_code = swap_condition (cond_code);
11214       std::swap (op1, op2);
11215     }
11217   rtx tmp = gen_reg_rtx (DImode);
11218   rtx tmp2 = gen_reg_rtx (DImode);
11219   emit_insn (gen_subdi3 (tmp, op1, op2));
11220   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11222   rtx tmp3;
11223   switch (cond_code)
11224     {
11225     default:
11226       gcc_unreachable ();
11227     case LT:
11228       tmp3 = tmp2;
11229       break;
11230     case GE:
11231       tmp3 = gen_reg_rtx (DImode);
11232       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11233       break;
11234     }
11236   convert_move (operands[0], tmp3, 1);
11238   DONE;
11241 (define_expand "cstore<mode>4_signed_imm"
11242   [(use (match_operator 1 "signed_comparison_operator"
11243          [(match_operand:GPR 2 "gpc_reg_operand")
11244           (match_operand:GPR 3 "immediate_operand")]))
11245    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11246   ""
11248   bool invert = false;
11250   enum rtx_code cond_code = GET_CODE (operands[1]);
11252   rtx op0 = operands[0];
11253   rtx op1 = operands[2];
11254   HOST_WIDE_INT val = INTVAL (operands[3]);
11256   if (cond_code == GE || cond_code == GT)
11257     {
11258       cond_code = reverse_condition (cond_code);
11259       invert = true;
11260     }
11262   if (cond_code == LE)
11263     val++;
11265   rtx tmp = gen_reg_rtx (<MODE>mode);
11266   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11267   rtx x = gen_reg_rtx (<MODE>mode);
11268   if (val < 0)
11269     emit_insn (gen_and<mode>3 (x, op1, tmp));
11270   else
11271     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11273   if (invert)
11274     {
11275       rtx tmp = gen_reg_rtx (<MODE>mode);
11276       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11277       x = tmp;
11278     }
11280   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11281   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11283   DONE;
11286 (define_expand "cstore<mode>4_unsigned_imm"
11287   [(use (match_operator 1 "unsigned_comparison_operator"
11288          [(match_operand:GPR 2 "gpc_reg_operand")
11289           (match_operand:GPR 3 "immediate_operand")]))
11290    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11291   ""
11293   bool invert = false;
11295   enum rtx_code cond_code = GET_CODE (operands[1]);
11297   rtx op0 = operands[0];
11298   rtx op1 = operands[2];
11299   HOST_WIDE_INT val = INTVAL (operands[3]);
11301   if (cond_code == GEU || cond_code == GTU)
11302     {
11303       cond_code = reverse_condition (cond_code);
11304       invert = true;
11305     }
11307   if (cond_code == LEU)
11308     val++;
11310   rtx tmp = gen_reg_rtx (<MODE>mode);
11311   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11312   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11313   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11314   rtx x = gen_reg_rtx (<MODE>mode);
11315   if (val < 0)
11316     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11317   else
11318     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11320   if (invert)
11321     {
11322       rtx tmp = gen_reg_rtx (<MODE>mode);
11323       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11324       x = tmp;
11325     }
11327   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11328   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11330   DONE;
11333 (define_expand "cstore<mode>4"
11334   [(use (match_operator 1 "rs6000_cbranch_operator"
11335          [(match_operand:GPR 2 "gpc_reg_operand")
11336           (match_operand:GPR 3 "reg_or_short_operand")]))
11337    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11338   ""
11340   /* Use ISEL if the user asked for it.  */
11341   if (TARGET_ISEL)
11342     rs6000_emit_sISEL (<MODE>mode, operands);
11344   /* Expanding EQ and NE directly to some machine instructions does not help
11345      but does hurt combine.  So don't.  */
11346   else if (GET_CODE (operands[1]) == EQ)
11347     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11348   else if (<MODE>mode == Pmode
11349            && GET_CODE (operands[1]) == NE)
11350     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11351   else if (GET_CODE (operands[1]) == NE)
11352     {
11353       rtx tmp = gen_reg_rtx (<MODE>mode);
11354       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11355       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11356     }
11358   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11359      etc. combinations magically work out just right.  */
11360   else if (<MODE>mode == Pmode
11361            && unsigned_comparison_operator (operands[1], VOIDmode))
11362     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11363                                            operands[2], operands[3]));
11365   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11366   else if (<MODE>mode == SImode && Pmode == DImode)
11367     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11368                                     operands[2], operands[3]));
11370   /* For signed comparisons against a constant, we can do some simple
11371      bit-twiddling.  */
11372   else if (signed_comparison_operator (operands[1], VOIDmode)
11373            && CONST_INT_P (operands[3]))
11374     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11375                                              operands[2], operands[3]));
11377   /* And similarly for unsigned comparisons.  */
11378   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11379            && CONST_INT_P (operands[3]))
11380     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11381                                                operands[2], operands[3]));
11383   /* We also do not want to use mfcr for signed comparisons.  */
11384   else if (<MODE>mode == Pmode
11385            && signed_comparison_operator (operands[1], VOIDmode))
11386     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11387                                          operands[2], operands[3]));
11389   /* Everything else, use the mfcr brute force.  */
11390   else
11391     rs6000_emit_sCOND (<MODE>mode, operands);
11393   DONE;
11396 (define_expand "cstore<mode>4"
11397   [(use (match_operator 1 "rs6000_cbranch_operator"
11398          [(match_operand:FP 2 "gpc_reg_operand")
11399           (match_operand:FP 3 "gpc_reg_operand")]))
11400    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11401   ""
11403   rs6000_emit_sCOND (<MODE>mode, operands);
11404   DONE;
11408 (define_expand "stack_protect_set"
11409   [(match_operand 0 "memory_operand" "")
11410    (match_operand 1 "memory_operand" "")]
11411   ""
11413 #ifdef TARGET_THREAD_SSP_OFFSET
11414   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11415   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11416   operands[1] = gen_rtx_MEM (Pmode, addr);
11417 #endif
11418   if (TARGET_64BIT)
11419     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11420   else
11421     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11422   DONE;
11425 (define_insn "stack_protect_setsi"
11426   [(set (match_operand:SI 0 "memory_operand" "=m")
11427         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11428    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11429   "TARGET_32BIT"
11430   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11431   [(set_attr "type" "three")
11432    (set_attr "length" "12")])
11434 (define_insn "stack_protect_setdi"
11435   [(set (match_operand:DI 0 "memory_operand" "=Y")
11436         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11437    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11438   "TARGET_64BIT"
11439   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11440   [(set_attr "type" "three")
11441    (set_attr "length" "12")])
11443 (define_expand "stack_protect_test"
11444   [(match_operand 0 "memory_operand" "")
11445    (match_operand 1 "memory_operand" "")
11446    (match_operand 2 "" "")]
11447   ""
11449   rtx test, op0, op1;
11450 #ifdef TARGET_THREAD_SSP_OFFSET
11451   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11452   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11453   operands[1] = gen_rtx_MEM (Pmode, addr);
11454 #endif
11455   op0 = operands[0];
11456   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11457   test = gen_rtx_EQ (VOIDmode, op0, op1);
11458   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11459   DONE;
11462 (define_insn "stack_protect_testsi"
11463   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11464         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11465                       (match_operand:SI 2 "memory_operand" "m,m")]
11466                      UNSPEC_SP_TEST))
11467    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11468    (clobber (match_scratch:SI 3 "=&r,&r"))]
11469   "TARGET_32BIT"
11470   "@
11471    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11472    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11473   [(set_attr "length" "16,20")])
11475 (define_insn "stack_protect_testdi"
11476   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11477         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11478                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11479                      UNSPEC_SP_TEST))
11480    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11481    (clobber (match_scratch:DI 3 "=&r,&r"))]
11482   "TARGET_64BIT"
11483   "@
11484    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11485    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11486   [(set_attr "length" "16,20")])
11489 ;; Here are the actual compare insns.
11490 (define_insn "*cmp<mode>_signed"
11491   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11492         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11493                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11494   ""
11495   "cmp<wd>%I2 %0,%1,%2"
11496   [(set_attr "type" "cmp")])
11498 (define_insn "*cmp<mode>_unsigned"
11499   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11500         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11501                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11502   ""
11503   "cmpl<wd>%I2 %0,%1,%2"
11504   [(set_attr "type" "cmp")])
11506 ;; If we are comparing a register for equality with a large constant,
11507 ;; we can do this with an XOR followed by a compare.  But this is profitable
11508 ;; only if the large constant is only used for the comparison (and in this
11509 ;; case we already have a register to reuse as scratch).
11511 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11512 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11514 (define_peephole2
11515   [(set (match_operand:SI 0 "register_operand")
11516         (match_operand:SI 1 "logical_const_operand" ""))
11517    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11518                        [(match_dup 0)
11519                         (match_operand:SI 2 "logical_const_operand" "")]))
11520    (set (match_operand:CC 4 "cc_reg_operand" "")
11521         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11522                     (match_dup 0)))
11523    (set (pc)
11524         (if_then_else (match_operator 6 "equality_operator"
11525                        [(match_dup 4) (const_int 0)])
11526                       (match_operand 7 "" "")
11527                       (match_operand 8 "" "")))]
11528   "peep2_reg_dead_p (3, operands[0])
11529    && peep2_reg_dead_p (4, operands[4])
11530    && REGNO (operands[0]) != REGNO (operands[5])"
11531  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11532   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11533   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11536   /* Get the constant we are comparing against, and see what it looks like
11537      when sign-extended from 16 to 32 bits.  Then see what constant we could
11538      XOR with SEXTC to get the sign-extended value.  */
11539   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11540                                               SImode,
11541                                               operands[1], operands[2]);
11542   HOST_WIDE_INT c = INTVAL (cnst);
11543   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11544   HOST_WIDE_INT xorv = c ^ sextc;
11546   operands[9] = GEN_INT (xorv);
11547   operands[10] = GEN_INT (sextc);
11550 ;; The following two insns don't exist as single insns, but if we provide
11551 ;; them, we can swap an add and compare, which will enable us to overlap more
11552 ;; of the required delay between a compare and branch.  We generate code for
11553 ;; them by splitting.
11555 (define_insn ""
11556   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11557         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11558                     (match_operand:SI 2 "short_cint_operand" "i")))
11559    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11560         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11561   ""
11562   "#"
11563   [(set_attr "length" "8")])
11565 (define_insn ""
11566   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11567         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11568                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11569    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11570         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11571   ""
11572   "#"
11573   [(set_attr "length" "8")])
11575 (define_split
11576   [(set (match_operand:CC 3 "cc_reg_operand" "")
11577         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11578                     (match_operand:SI 2 "short_cint_operand" "")))
11579    (set (match_operand:SI 0 "gpc_reg_operand" "")
11580         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11581   ""
11582   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11583    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11585 (define_split
11586   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11587         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11588                        (match_operand:SI 2 "u_short_cint_operand" "")))
11589    (set (match_operand:SI 0 "gpc_reg_operand" "")
11590         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11591   ""
11592   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11593    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11595 ;; Only need to compare second words if first words equal
11596 (define_insn "*cmp<mode>_internal1"
11597   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11598         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11599                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11600   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11601    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11602   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11603   [(set_attr "type" "fpcompare")
11604    (set_attr "length" "12")])
11606 (define_insn_and_split "*cmp<mode>_internal2"
11607   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11608         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11609                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11610     (clobber (match_scratch:DF 3 "=d"))
11611     (clobber (match_scratch:DF 4 "=d"))
11612     (clobber (match_scratch:DF 5 "=d"))
11613     (clobber (match_scratch:DF 6 "=d"))
11614     (clobber (match_scratch:DF 7 "=d"))
11615     (clobber (match_scratch:DF 8 "=d"))
11616     (clobber (match_scratch:DF 9 "=d"))
11617     (clobber (match_scratch:DF 10 "=d"))
11618     (clobber (match_scratch:GPR 11 "=b"))]
11619   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11620    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11621   "#"
11622   "&& reload_completed"
11623   [(set (match_dup 3) (match_dup 14))
11624    (set (match_dup 4) (match_dup 15))
11625    (set (match_dup 9) (abs:DF (match_dup 5)))
11626    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11627    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11628                            (label_ref (match_dup 12))
11629                            (pc)))
11630    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11631    (set (pc) (label_ref (match_dup 13)))
11632    (match_dup 12)
11633    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11634    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11635    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11636    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11637    (match_dup 13)]
11639   REAL_VALUE_TYPE rv;
11640   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11641   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11643   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11644   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11645   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11646   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11647   operands[12] = gen_label_rtx ();
11648   operands[13] = gen_label_rtx ();
11649   real_inf (&rv);
11650   operands[14] = force_const_mem (DFmode,
11651                                   const_double_from_real_value (rv, DFmode));
11652   operands[15] = force_const_mem (DFmode,
11653                                   const_double_from_real_value (dconst0,
11654                                                                 DFmode));
11655   if (TARGET_TOC)
11656     {
11657       rtx tocref;
11658       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11659       operands[14] = gen_const_mem (DFmode, tocref);
11660       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11661       operands[15] = gen_const_mem (DFmode, tocref);
11662       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11663       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11664     }
11667 ;; Now we have the scc insns.  We can do some combinations because of the
11668 ;; way the machine works.
11670 ;; Note that this is probably faster if we can put an insn between the
11671 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11672 ;; cases the insns below which don't use an intermediate CR field will
11673 ;; be used instead.
11674 (define_insn ""
11675   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11676         (match_operator:SI 1 "scc_comparison_operator"
11677                            [(match_operand 2 "cc_reg_operand" "y")
11678                             (const_int 0)]))]
11679   ""
11680   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11681   [(set (attr "type")
11682      (cond [(match_test "TARGET_MFCRF")
11683                 (const_string "mfcrf")
11684            ]
11685         (const_string "mfcr")))
11686    (set_attr "length" "8")])
11688 ;; Same as above, but get the GT bit.
11689 (define_insn "move_from_CR_gt_bit"
11690   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11691         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11692   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11693   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11694   [(set_attr "type" "mfcr")
11695    (set_attr "length" "8")])
11697 ;; Same as above, but get the OV/ORDERED bit.
11698 (define_insn "move_from_CR_ov_bit"
11699   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11700         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11701                    UNSPEC_MV_CR_OV))]
11702   "TARGET_ISEL"
11703   "mfcr %0\;rlwinm %0,%0,%t1,1"
11704   [(set_attr "type" "mfcr")
11705    (set_attr "length" "8")])
11707 (define_insn ""
11708   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11709         (match_operator:DI 1 "scc_comparison_operator"
11710                            [(match_operand 2 "cc_reg_operand" "y")
11711                             (const_int 0)]))]
11712   "TARGET_POWERPC64"
11713   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11714   [(set (attr "type")
11715      (cond [(match_test "TARGET_MFCRF")
11716                 (const_string "mfcrf")
11717            ]
11718         (const_string "mfcr")))
11719    (set_attr "length" "8")])
11721 (define_insn ""
11722   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11723         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11724                                        [(match_operand 2 "cc_reg_operand" "y,y")
11725                                         (const_int 0)])
11726                     (const_int 0)))
11727    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11728         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11729   "TARGET_32BIT"
11730   "@
11731    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11732    #"
11733   [(set_attr "type" "shift")
11734    (set_attr "dot" "yes")
11735    (set_attr "length" "8,16")])
11737 (define_split
11738   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11739         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11740                                        [(match_operand 2 "cc_reg_operand" "")
11741                                         (const_int 0)])
11742                     (const_int 0)))
11743    (set (match_operand:SI 3 "gpc_reg_operand" "")
11744         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11745   "TARGET_32BIT && reload_completed"
11746   [(set (match_dup 3)
11747         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11748    (set (match_dup 0)
11749         (compare:CC (match_dup 3)
11750                     (const_int 0)))]
11751   "")
11753 (define_insn ""
11754   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11755         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11756                                       [(match_operand 2 "cc_reg_operand" "y")
11757                                        (const_int 0)])
11758                    (match_operand:SI 3 "const_int_operand" "n")))]
11759   ""
11760   "*
11762   int is_bit = ccr_bit (operands[1], 1);
11763   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11764   int count;
11766   if (is_bit >= put_bit)
11767     count = is_bit - put_bit;
11768   else
11769     count = 32 - (put_bit - is_bit);
11771   operands[4] = GEN_INT (count);
11772   operands[5] = GEN_INT (put_bit);
11774   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11776   [(set (attr "type")
11777      (cond [(match_test "TARGET_MFCRF")
11778                 (const_string "mfcrf")
11779            ]
11780         (const_string "mfcr")))
11781    (set_attr "length" "8")])
11783 (define_insn ""
11784   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11785         (compare:CC
11786          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11787                                        [(match_operand 2 "cc_reg_operand" "y,y")
11788                                         (const_int 0)])
11789                     (match_operand:SI 3 "const_int_operand" "n,n"))
11790          (const_int 0)))
11791    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11792         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11793                    (match_dup 3)))]
11794   ""
11795   "*
11797   int is_bit = ccr_bit (operands[1], 1);
11798   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11799   int count;
11801   /* Force split for non-cc0 compare.  */
11802   if (which_alternative == 1)
11803      return \"#\";
11805   if (is_bit >= put_bit)
11806     count = is_bit - put_bit;
11807   else
11808     count = 32 - (put_bit - is_bit);
11810   operands[5] = GEN_INT (count);
11811   operands[6] = GEN_INT (put_bit);
11813   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11815   [(set_attr "type" "shift")
11816    (set_attr "dot" "yes")
11817    (set_attr "length" "8,16")])
11819 (define_split
11820   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11821         (compare:CC
11822          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11823                                        [(match_operand 2 "cc_reg_operand" "")
11824                                         (const_int 0)])
11825                     (match_operand:SI 3 "const_int_operand" ""))
11826          (const_int 0)))
11827    (set (match_operand:SI 4 "gpc_reg_operand" "")
11828         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11829                    (match_dup 3)))]
11830   "reload_completed"
11831   [(set (match_dup 4)
11832         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11833                    (match_dup 3)))
11834    (set (match_dup 0)
11835         (compare:CC (match_dup 4)
11836                     (const_int 0)))]
11837   "")
11840 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11841                               (DI "rKJI")])
11843 (define_insn_and_split "eq<mode>3"
11844   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11845         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11846                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11847    (clobber (match_scratch:GPR 3 "=r"))
11848    (clobber (match_scratch:GPR 4 "=r"))]
11849   ""
11850   "#"
11851   ""
11852   [(set (match_dup 4)
11853         (clz:GPR (match_dup 3)))
11854    (set (match_dup 0)
11855         (lshiftrt:GPR (match_dup 4)
11856                       (match_dup 5)))]
11858   operands[3] = rs6000_emit_eqne (<MODE>mode,
11859                                   operands[1], operands[2], operands[3]);
11861   if (GET_CODE (operands[4]) == SCRATCH)
11862     operands[4] = gen_reg_rtx (<MODE>mode);
11864   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11866   [(set (attr "length")
11867         (if_then_else (match_test "operands[2] == const0_rtx")
11868                       (const_string "8")
11869                       (const_string "12")))])
11871 (define_insn_and_split "ne<mode>3"
11872   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11873         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11874               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11875    (clobber (match_scratch:P 3 "=r"))
11876    (clobber (match_scratch:P 4 "=r"))
11877    (clobber (reg:P CA_REGNO))]
11878   "!TARGET_ISEL"
11879   "#"
11880   ""
11881   [(parallel [(set (match_dup 4)
11882                    (plus:P (match_dup 3)
11883                            (const_int -1)))
11884               (set (reg:P CA_REGNO)
11885                    (ne:P (match_dup 3)
11886                          (const_int 0)))])
11887    (parallel [(set (match_dup 0)
11888                    (plus:P (plus:P (not:P (match_dup 4))
11889                                    (reg:P CA_REGNO))
11890                            (match_dup 3)))
11891               (clobber (reg:P CA_REGNO))])]
11893   operands[3] = rs6000_emit_eqne (<MODE>mode,
11894                                   operands[1], operands[2], operands[3]);
11896   if (GET_CODE (operands[4]) == SCRATCH)
11897     operands[4] = gen_reg_rtx (<MODE>mode);
11899   [(set (attr "length")
11900         (if_then_else (match_test "operands[2] == const0_rtx")
11901                       (const_string "8")
11902                       (const_string "12")))])
11904 (define_insn_and_split "*neg_eq_<mode>"
11905   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11906         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11907                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11908    (clobber (match_scratch:P 3 "=r"))
11909    (clobber (match_scratch:P 4 "=r"))
11910    (clobber (reg:P CA_REGNO))]
11911   ""
11912   "#"
11913   ""
11914   [(parallel [(set (match_dup 4)
11915                    (plus:P (match_dup 3)
11916                            (const_int -1)))
11917               (set (reg:P CA_REGNO)
11918                    (ne:P (match_dup 3)
11919                          (const_int 0)))])
11920    (parallel [(set (match_dup 0)
11921                    (plus:P (reg:P CA_REGNO)
11922                            (const_int -1)))
11923               (clobber (reg:P CA_REGNO))])]
11925   operands[3] = rs6000_emit_eqne (<MODE>mode,
11926                                   operands[1], operands[2], operands[3]);
11928   if (GET_CODE (operands[4]) == SCRATCH)
11929     operands[4] = gen_reg_rtx (<MODE>mode);
11931   [(set (attr "length")
11932         (if_then_else (match_test "operands[2] == const0_rtx")
11933                       (const_string "8")
11934                       (const_string "12")))])
11936 (define_insn_and_split "*neg_ne_<mode>"
11937   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11938         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11939                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11940    (clobber (match_scratch:P 3 "=r"))
11941    (clobber (match_scratch:P 4 "=r"))
11942    (clobber (reg:P CA_REGNO))]
11943   ""
11944   "#"
11945   ""
11946   [(parallel [(set (match_dup 4)
11947                    (neg:P (match_dup 3)))
11948               (set (reg:P CA_REGNO)
11949                    (eq:P (match_dup 3)
11950                          (const_int 0)))])
11951    (parallel [(set (match_dup 0)
11952                    (plus:P (reg:P CA_REGNO)
11953                            (const_int -1)))
11954               (clobber (reg:P CA_REGNO))])]
11956   operands[3] = rs6000_emit_eqne (<MODE>mode,
11957                                   operands[1], operands[2], operands[3]);
11959   if (GET_CODE (operands[4]) == SCRATCH)
11960     operands[4] = gen_reg_rtx (<MODE>mode);
11962   [(set (attr "length")
11963         (if_then_else (match_test "operands[2] == const0_rtx")
11964                       (const_string "8")
11965                       (const_string "12")))])
11967 (define_insn_and_split "*plus_eq_<mode>"
11968   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11969         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11970                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11971                 (match_operand:P 3 "gpc_reg_operand" "r")))
11972    (clobber (match_scratch:P 4 "=r"))
11973    (clobber (match_scratch:P 5 "=r"))
11974    (clobber (reg:P CA_REGNO))]
11975   ""
11976   "#"
11977   ""
11978   [(parallel [(set (match_dup 5)
11979                    (neg:P (match_dup 4)))
11980               (set (reg:P CA_REGNO)
11981                    (eq:P (match_dup 4)
11982                          (const_int 0)))])
11983    (parallel [(set (match_dup 0)
11984                    (plus:P (match_dup 3)
11985                            (reg:P CA_REGNO)))
11986               (clobber (reg:P CA_REGNO))])]
11988   operands[4] = rs6000_emit_eqne (<MODE>mode,
11989                                   operands[1], operands[2], operands[4]);
11991   if (GET_CODE (operands[5]) == SCRATCH)
11992     operands[5] = gen_reg_rtx (<MODE>mode);
11994   [(set (attr "length")
11995         (if_then_else (match_test "operands[2] == const0_rtx")
11996                       (const_string "8")
11997                       (const_string "12")))])
11999 (define_insn_and_split "*plus_ne_<mode>"
12000   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12001         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12002                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12003                 (match_operand:P 3 "gpc_reg_operand" "r")))
12004    (clobber (match_scratch:P 4 "=r"))
12005    (clobber (match_scratch:P 5 "=r"))
12006    (clobber (reg:P CA_REGNO))]
12007   ""
12008   "#"
12009   ""
12010   [(parallel [(set (match_dup 5)
12011                    (plus:P (match_dup 4)
12012                            (const_int -1)))
12013               (set (reg:P CA_REGNO)
12014                    (ne:P (match_dup 4)
12015                          (const_int 0)))])
12016    (parallel [(set (match_dup 0)
12017                    (plus:P (match_dup 3)
12018                            (reg:P CA_REGNO)))
12019               (clobber (reg:P CA_REGNO))])]
12021   operands[4] = rs6000_emit_eqne (<MODE>mode,
12022                                   operands[1], operands[2], operands[4]);
12024   if (GET_CODE (operands[5]) == SCRATCH)
12025     operands[5] = gen_reg_rtx (<MODE>mode);
12027   [(set (attr "length")
12028         (if_then_else (match_test "operands[2] == const0_rtx")
12029                       (const_string "8")
12030                       (const_string "12")))])
12032 (define_insn_and_split "*minus_eq_<mode>"
12033   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12034         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12035                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12036                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12037    (clobber (match_scratch:P 4 "=r"))
12038    (clobber (match_scratch:P 5 "=r"))
12039    (clobber (reg:P CA_REGNO))]
12040   ""
12041   "#"
12042   ""
12043   [(parallel [(set (match_dup 5)
12044                    (plus:P (match_dup 4)
12045                            (const_int -1)))
12046               (set (reg:P CA_REGNO)
12047                    (ne:P (match_dup 4)
12048                          (const_int 0)))])
12049    (parallel [(set (match_dup 0)
12050                    (plus:P (plus:P (match_dup 3)
12051                                    (reg:P CA_REGNO))
12052                            (const_int -1)))
12053               (clobber (reg:P CA_REGNO))])]
12055   operands[4] = rs6000_emit_eqne (<MODE>mode,
12056                                   operands[1], operands[2], operands[4]);
12058   if (GET_CODE (operands[5]) == SCRATCH)
12059     operands[5] = gen_reg_rtx (<MODE>mode);
12061   [(set (attr "length")
12062         (if_then_else (match_test "operands[2] == const0_rtx")
12063                       (const_string "8")
12064                       (const_string "12")))])
12066 (define_insn_and_split "*minus_ne_<mode>"
12067   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12068         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12069                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12070                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12071    (clobber (match_scratch:P 4 "=r"))
12072    (clobber (match_scratch:P 5 "=r"))
12073    (clobber (reg:P CA_REGNO))]
12074   ""
12075   "#"
12076   ""
12077   [(parallel [(set (match_dup 5)
12078                    (neg:P (match_dup 4)))
12079               (set (reg:P CA_REGNO)
12080                    (eq:P (match_dup 4)
12081                          (const_int 0)))])
12082    (parallel [(set (match_dup 0)
12083                    (plus:P (plus:P (match_dup 3)
12084                                    (reg:P CA_REGNO))
12085                            (const_int -1)))
12086               (clobber (reg:P CA_REGNO))])]
12088   operands[4] = rs6000_emit_eqne (<MODE>mode,
12089                                   operands[1], operands[2], operands[4]);
12091   if (GET_CODE (operands[5]) == SCRATCH)
12092     operands[5] = gen_reg_rtx (<MODE>mode);
12094   [(set (attr "length")
12095         (if_then_else (match_test "operands[2] == const0_rtx")
12096                       (const_string "8")
12097                       (const_string "12")))])
12099 (define_insn_and_split "*eqsi3_ext<mode>"
12100   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12101         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12102                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12103    (clobber (match_scratch:SI 3 "=r"))
12104    (clobber (match_scratch:SI 4 "=r"))]
12105   ""
12106   "#"
12107   ""
12108   [(set (match_dup 4)
12109         (clz:SI (match_dup 3)))
12110    (set (match_dup 0)
12111         (zero_extend:EXTSI
12112           (lshiftrt:SI (match_dup 4)
12113                        (const_int 5))))]
12115   operands[3] = rs6000_emit_eqne (SImode,
12116                                   operands[1], operands[2], operands[3]);
12118   if (GET_CODE (operands[4]) == SCRATCH)
12119     operands[4] = gen_reg_rtx (SImode);
12121   [(set (attr "length")
12122         (if_then_else (match_test "operands[2] == const0_rtx")
12123                       (const_string "8")
12124                       (const_string "12")))])
12126 (define_insn_and_split "*nesi3_ext<mode>"
12127   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12128         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12129                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12130    (clobber (match_scratch:SI 3 "=r"))
12131    (clobber (match_scratch:SI 4 "=r"))
12132    (clobber (match_scratch:EXTSI 5 "=r"))]
12133   ""
12134   "#"
12135   ""
12136   [(set (match_dup 4)
12137         (clz:SI (match_dup 3)))
12138    (set (match_dup 5)
12139         (zero_extend:EXTSI
12140           (lshiftrt:SI (match_dup 4)
12141                        (const_int 5))))
12142    (set (match_dup 0)
12143         (xor:EXTSI (match_dup 5)
12144                    (const_int 1)))]
12146   operands[3] = rs6000_emit_eqne (SImode,
12147                                   operands[1], operands[2], operands[3]);
12149   if (GET_CODE (operands[4]) == SCRATCH)
12150     operands[4] = gen_reg_rtx (SImode);
12151   if (GET_CODE (operands[5]) == SCRATCH)
12152     operands[5] = gen_reg_rtx (<MODE>mode);
12154   [(set (attr "length")
12155         (if_then_else (match_test "operands[2] == const0_rtx")
12156                       (const_string "12")
12157                       (const_string "16")))])
12159 ;; Define both directions of branch and return.  If we need a reload
12160 ;; register, we'd rather use CR0 since it is much easier to copy a
12161 ;; register CC value to there.
12163 (define_insn ""
12164   [(set (pc)
12165         (if_then_else (match_operator 1 "branch_comparison_operator"
12166                                       [(match_operand 2
12167                                                       "cc_reg_operand" "y")
12168                                        (const_int 0)])
12169                       (label_ref (match_operand 0 "" ""))
12170                       (pc)))]
12171   ""
12172   "*
12174   return output_cbranch (operands[1], \"%l0\", 0, insn);
12176   [(set_attr "type" "branch")])
12178 (define_insn ""
12179   [(set (pc)
12180         (if_then_else (match_operator 0 "branch_comparison_operator"
12181                                       [(match_operand 1
12182                                                       "cc_reg_operand" "y")
12183                                        (const_int 0)])
12184                       (any_return)
12185                       (pc)))]
12186   "<return_pred>"
12187   "*
12189   return output_cbranch (operands[0], NULL, 0, insn);
12191   [(set_attr "type" "jmpreg")
12192    (set_attr "length" "4")])
12194 (define_insn ""
12195   [(set (pc)
12196         (if_then_else (match_operator 1 "branch_comparison_operator"
12197                                       [(match_operand 2
12198                                                       "cc_reg_operand" "y")
12199                                        (const_int 0)])
12200                       (pc)
12201                       (label_ref (match_operand 0 "" ""))))]
12202   ""
12203   "*
12205   return output_cbranch (operands[1], \"%l0\", 1, insn);
12207   [(set_attr "type" "branch")])
12209 (define_insn ""
12210   [(set (pc)
12211         (if_then_else (match_operator 0 "branch_comparison_operator"
12212                                       [(match_operand 1
12213                                                       "cc_reg_operand" "y")
12214                                        (const_int 0)])
12215                       (pc)
12216                       (any_return)))]
12217   "<return_pred>"
12218   "*
12220   return output_cbranch (operands[0], NULL, 1, insn);
12222   [(set_attr "type" "jmpreg")
12223    (set_attr "length" "4")])
12225 ;; Logic on condition register values.
12227 ; This pattern matches things like
12228 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12229 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12230 ;                                  (const_int 1)))
12231 ; which are generated by the branch logic.
12232 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12234 (define_insn "*cceq_ior_compare"
12235   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12236         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12237                         [(match_operator:SI 2
12238                                       "branch_positive_comparison_operator"
12239                                       [(match_operand 3
12240                                                       "cc_reg_operand" "y,y")
12241                                        (const_int 0)])
12242                          (match_operator:SI 4
12243                                       "branch_positive_comparison_operator"
12244                                       [(match_operand 5
12245                                                       "cc_reg_operand" "0,y")
12246                                        (const_int 0)])])
12247                       (const_int 1)))]
12248   ""
12249   "cr%q1 %E0,%j2,%j4"
12250   [(set_attr "type" "cr_logical,delayed_cr")])
12252 ; Why is the constant -1 here, but 1 in the previous pattern?
12253 ; Because ~1 has all but the low bit set.
12254 (define_insn ""
12255   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12256         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12257                         [(not:SI (match_operator:SI 2
12258                                       "branch_positive_comparison_operator"
12259                                       [(match_operand 3
12260                                                       "cc_reg_operand" "y,y")
12261                                        (const_int 0)]))
12262                          (match_operator:SI 4
12263                                 "branch_positive_comparison_operator"
12264                                 [(match_operand 5
12265                                                 "cc_reg_operand" "0,y")
12266                                  (const_int 0)])])
12267                       (const_int -1)))]
12268   ""
12269   "cr%q1 %E0,%j2,%j4"
12270   [(set_attr "type" "cr_logical,delayed_cr")])
12272 (define_insn "*cceq_rev_compare"
12273   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12274         (compare:CCEQ (match_operator:SI 1
12275                                       "branch_positive_comparison_operator"
12276                                       [(match_operand 2
12277                                                       "cc_reg_operand" "0,y")
12278                                        (const_int 0)])
12279                       (const_int 0)))]
12280   ""
12281   "crnot %E0,%j1"
12282   [(set_attr "type" "cr_logical,delayed_cr")])
12284 ;; If we are comparing the result of two comparisons, this can be done
12285 ;; using creqv or crxor.
12287 (define_insn_and_split ""
12288   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12289         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12290                               [(match_operand 2 "cc_reg_operand" "y")
12291                                (const_int 0)])
12292                       (match_operator 3 "branch_comparison_operator"
12293                               [(match_operand 4 "cc_reg_operand" "y")
12294                                (const_int 0)])))]
12295   ""
12296   "#"
12297   ""
12298   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12299                                     (match_dup 5)))]
12300   "
12302   int positive_1, positive_2;
12304   positive_1 = branch_positive_comparison_operator (operands[1],
12305                                                     GET_MODE (operands[1]));
12306   positive_2 = branch_positive_comparison_operator (operands[3],
12307                                                     GET_MODE (operands[3]));
12309   if (! positive_1)
12310     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12311                                                             GET_CODE (operands[1])),
12312                                   SImode,
12313                                   operands[2], const0_rtx);
12314   else if (GET_MODE (operands[1]) != SImode)
12315     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12316                                   operands[2], const0_rtx);
12318   if (! positive_2)
12319     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12320                                                             GET_CODE (operands[3])),
12321                                   SImode,
12322                                   operands[4], const0_rtx);
12323   else if (GET_MODE (operands[3]) != SImode)
12324     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12325                                   operands[4], const0_rtx);
12327   if (positive_1 == positive_2)
12328     {
12329       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12330       operands[5] = constm1_rtx;
12331     }
12332   else
12333     {
12334       operands[5] = const1_rtx;
12335     }
12338 ;; Unconditional branch and return.
12340 (define_insn "jump"
12341   [(set (pc)
12342         (label_ref (match_operand 0 "" "")))]
12343   ""
12344   "b %l0"
12345   [(set_attr "type" "branch")])
12347 (define_insn "<return_str>return"
12348   [(any_return)]
12349   "<return_pred>"
12350   "blr"
12351   [(set_attr "type" "jmpreg")])
12353 (define_expand "indirect_jump"
12354   [(set (pc) (match_operand 0 "register_operand" ""))])
12356 (define_insn "*indirect_jump<mode>"
12357   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12358   ""
12359   "@
12360    bctr
12361    blr"
12362   [(set_attr "type" "jmpreg")])
12364 ;; Table jump for switch statements:
12365 (define_expand "tablejump"
12366   [(use (match_operand 0 "" ""))
12367    (use (label_ref (match_operand 1 "" "")))]
12368   ""
12369   "
12371   if (TARGET_32BIT)
12372     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12373   else
12374     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12375   DONE;
12378 (define_expand "tablejumpsi"
12379   [(set (match_dup 3)
12380         (plus:SI (match_operand:SI 0 "" "")
12381                  (match_dup 2)))
12382    (parallel [(set (pc) (match_dup 3))
12383               (use (label_ref (match_operand 1 "" "")))])]
12384   "TARGET_32BIT"
12385   "
12386 { operands[0] = force_reg (SImode, operands[0]);
12387   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12388   operands[3] = gen_reg_rtx (SImode);
12391 (define_expand "tablejumpdi"
12392   [(set (match_dup 4)
12393         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12394    (set (match_dup 3)
12395         (plus:DI (match_dup 4)
12396                  (match_dup 2)))
12397    (parallel [(set (pc) (match_dup 3))
12398               (use (label_ref (match_operand 1 "" "")))])]
12399   "TARGET_64BIT"
12400   "
12401 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12402   operands[3] = gen_reg_rtx (DImode);
12403   operands[4] = gen_reg_rtx (DImode);
12406 (define_insn "*tablejump<mode>_internal1"
12407   [(set (pc)
12408         (match_operand:P 0 "register_operand" "c,*l"))
12409    (use (label_ref (match_operand 1 "" "")))]
12410   ""
12411   "@
12412    bctr
12413    blr"
12414   [(set_attr "type" "jmpreg")])
12416 (define_insn "nop"
12417   [(unspec [(const_int 0)] UNSPEC_NOP)]
12418   ""
12419   "nop")
12421 (define_insn "group_ending_nop"
12422   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12423   ""
12424   "*
12426   if (rs6000_cpu_attr == CPU_POWER6)
12427     return \"ori 1,1,0\";
12428   return \"ori 2,2,0\";
12431 ;; Define the subtract-one-and-jump insns, starting with the template
12432 ;; so loop.c knows what to generate.
12434 (define_expand "doloop_end"
12435   [(use (match_operand 0 "" ""))        ; loop pseudo
12436    (use (match_operand 1 "" ""))]       ; label
12437   ""
12438   "
12440   if (TARGET_64BIT)
12441     {
12442       if (GET_MODE (operands[0]) != DImode)
12443         FAIL;
12444       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12445     }
12446   else
12447     {
12448       if (GET_MODE (operands[0]) != SImode)
12449         FAIL;
12450       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12451     }
12452   DONE;
12455 (define_expand "ctr<mode>"
12456   [(parallel [(set (pc)
12457                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12458                                      (const_int 1))
12459                                  (label_ref (match_operand 1 "" ""))
12460                                  (pc)))
12461               (set (match_dup 0)
12462                    (plus:P (match_dup 0)
12463                             (const_int -1)))
12464               (unspec [(const_int 0)] UNSPEC_DOLOOP)
12465               (clobber (match_scratch:CC 2 ""))
12466               (clobber (match_scratch:P 3 ""))])]
12467   ""
12468   "")
12470 ;; We need to be able to do this for any operand, including MEM, or we
12471 ;; will cause reload to blow up since we don't allow output reloads on
12472 ;; JUMP_INSNs.
12473 ;; For the length attribute to be calculated correctly, the
12474 ;; label MUST be operand 0.
12475 ;; The UNSPEC is present to prevent combine creating this pattern.
12477 (define_insn "*ctr<mode>_internal1"
12478   [(set (pc)
12479         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12480                           (const_int 1))
12481                       (label_ref (match_operand 0 "" ""))
12482                       (pc)))
12483    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12484         (plus:P (match_dup 1)
12485                  (const_int -1)))
12486    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12487    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12488    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12489   ""
12490   "*
12492   if (which_alternative != 0)
12493     return \"#\";
12494   else if (get_attr_length (insn) == 4)
12495     return \"bdnz %l0\";
12496   else
12497     return \"bdz $+8\;b %l0\";
12499   [(set_attr "type" "branch")
12500    (set_attr "length" "*,16,20,20")])
12502 (define_insn "*ctr<mode>_internal2"
12503   [(set (pc)
12504         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12505                           (const_int 1))
12506                       (pc)
12507                       (label_ref (match_operand 0 "" ""))))
12508    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12509         (plus:P (match_dup 1)
12510                  (const_int -1)))
12511    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12512    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12513    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12514   ""
12515   "*
12517   if (which_alternative != 0)
12518     return \"#\";
12519   else if (get_attr_length (insn) == 4)
12520     return \"bdz %l0\";
12521   else
12522     return \"bdnz $+8\;b %l0\";
12524   [(set_attr "type" "branch")
12525    (set_attr "length" "*,16,20,20")])
12527 ;; Similar but use EQ
12529 (define_insn "*ctr<mode>_internal5"
12530   [(set (pc)
12531         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12532                           (const_int 1))
12533                       (label_ref (match_operand 0 "" ""))
12534                       (pc)))
12535    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12536         (plus:P (match_dup 1)
12537                  (const_int -1)))
12538    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12539    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12540    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12541   ""
12542   "*
12544   if (which_alternative != 0)
12545     return \"#\";
12546   else if (get_attr_length (insn) == 4)
12547     return \"bdz %l0\";
12548   else
12549     return \"bdnz $+8\;b %l0\";
12551   [(set_attr "type" "branch")
12552    (set_attr "length" "*,16,20,20")])
12554 (define_insn "*ctr<mode>_internal6"
12555   [(set (pc)
12556         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12557                           (const_int 1))
12558                       (pc)
12559                       (label_ref (match_operand 0 "" ""))))
12560    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12561         (plus:P (match_dup 1)
12562                  (const_int -1)))
12563    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12564    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12565    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12566   ""
12567   "*
12569   if (which_alternative != 0)
12570     return \"#\";
12571   else if (get_attr_length (insn) == 4)
12572     return \"bdnz %l0\";
12573   else
12574     return \"bdz $+8\;b %l0\";
12576   [(set_attr "type" "branch")
12577    (set_attr "length" "*,16,20,20")])
12579 ;; Now the splitters if we could not allocate the CTR register
12581 (define_split
12582   [(set (pc)
12583         (if_then_else (match_operator 2 "comparison_operator"
12584                                       [(match_operand:P 1 "gpc_reg_operand" "")
12585                                        (const_int 1)])
12586                       (match_operand 5 "" "")
12587                       (match_operand 6 "" "")))
12588    (set (match_operand:P 0 "int_reg_operand" "")
12589         (plus:P (match_dup 1) (const_int -1)))
12590    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12591    (clobber (match_scratch:CC 3 ""))
12592    (clobber (match_scratch:P 4 ""))]
12593   "reload_completed"
12594   [(set (match_dup 3)
12595         (compare:CC (match_dup 1)
12596                     (const_int 1)))
12597    (set (match_dup 0)
12598         (plus:P (match_dup 1)
12599                 (const_int -1)))
12600    (set (pc) (if_then_else (match_dup 7)
12601                            (match_dup 5)
12602                            (match_dup 6)))]
12603   "
12604 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12605                                 operands[3], const0_rtx); }")
12607 (define_split
12608   [(set (pc)
12609         (if_then_else (match_operator 2 "comparison_operator"
12610                                       [(match_operand:P 1 "gpc_reg_operand" "")
12611                                        (const_int 1)])
12612                       (match_operand 5 "" "")
12613                       (match_operand 6 "" "")))
12614    (set (match_operand:P 0 "nonimmediate_operand" "")
12615         (plus:P (match_dup 1) (const_int -1)))
12616    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12617    (clobber (match_scratch:CC 3 ""))
12618    (clobber (match_scratch:P 4 ""))]
12619   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12620   [(set (match_dup 3)
12621         (compare:CC (match_dup 1)
12622                     (const_int 1)))
12623    (set (match_dup 4)
12624         (plus:P (match_dup 1)
12625                 (const_int -1)))
12626    (set (match_dup 0)
12627         (match_dup 4))
12628    (set (pc) (if_then_else (match_dup 7)
12629                            (match_dup 5)
12630                            (match_dup 6)))]
12631   "
12632 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12633                                 operands[3], const0_rtx); }")
12635 (define_insn "trap"
12636   [(trap_if (const_int 1) (const_int 0))]
12637   ""
12638   "trap"
12639   [(set_attr "type" "trap")])
12641 (define_expand "ctrap<mode>4"
12642   [(trap_if (match_operator 0 "ordered_comparison_operator"
12643                             [(match_operand:GPR 1 "register_operand")
12644                              (match_operand:GPR 2 "reg_or_short_operand")])
12645             (match_operand 3 "zero_constant" ""))]
12646   ""
12647   "")
12649 (define_insn ""
12650   [(trap_if (match_operator 0 "ordered_comparison_operator"
12651                             [(match_operand:GPR 1 "register_operand" "r")
12652                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12653             (const_int 0))]
12654   ""
12655   "t<wd>%V0%I2 %1,%2"
12656   [(set_attr "type" "trap")])
12658 ;; Insns related to generating the function prologue and epilogue.
12660 (define_expand "prologue"
12661   [(use (const_int 0))]
12662   ""
12664   rs6000_emit_prologue ();
12665   if (!TARGET_SCHED_PROLOG)
12666     emit_insn (gen_blockage ());
12667   DONE;
12670 (define_insn "*movesi_from_cr_one"
12671   [(match_parallel 0 "mfcr_operation"
12672                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12673                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12674                                      (match_operand 3 "immediate_operand" "n")]
12675                           UNSPEC_MOVESI_FROM_CR))])]
12676   "TARGET_MFCRF"
12677   "*
12679   int mask = 0;
12680   int i;
12681   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12682   {
12683     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12684     operands[4] = GEN_INT (mask);
12685     output_asm_insn (\"mfcr %1,%4\", operands);
12686   }
12687   return \"\";
12689   [(set_attr "type" "mfcrf")])
12691 (define_insn "movesi_from_cr"
12692   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12693         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12694                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12695                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12696                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12697                    UNSPEC_MOVESI_FROM_CR))]
12698   ""
12699   "mfcr %0"
12700   [(set_attr "type" "mfcr")])
12702 (define_insn "*crsave"
12703   [(match_parallel 0 "crsave_operation"
12704                    [(set (match_operand:SI 1 "memory_operand" "=m")
12705                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12706   ""
12707   "stw %2,%1"
12708   [(set_attr "type" "store")])
12710 (define_insn "*stmw"
12711   [(match_parallel 0 "stmw_operation"
12712                    [(set (match_operand:SI 1 "memory_operand" "=m")
12713                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12714   "TARGET_MULTIPLE"
12715   "stmw %2,%1"
12716   [(set_attr "type" "store")
12717    (set_attr "update" "yes")
12718    (set_attr "indexed" "yes")])
12720 ; The following comment applies to:
12721 ;     save_gpregs_*
12722 ;     save_fpregs_*
12723 ;     restore_gpregs*
12724 ;     return_and_restore_gpregs*
12725 ;     return_and_restore_fpregs*
12726 ;     return_and_restore_fpregs_aix*
12728 ; The out-of-line save / restore functions expects one input argument.
12729 ; Since those are not standard call_insn's, we must avoid using
12730 ; MATCH_OPERAND for that argument. That way the register rename
12731 ; optimization will not try to rename this register.
12732 ; Each pattern is repeated for each possible register number used in 
12733 ; various ABIs (r11, r1, and for some functions r12)
12735 (define_insn "*save_gpregs_<mode>_r11"
12736   [(match_parallel 0 "any_parallel_operand"
12737                    [(clobber (reg:P LR_REGNO))
12738                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12739                     (use (reg:P 11))
12740                     (set (match_operand:P 2 "memory_operand" "=m")
12741                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12742   ""
12743   "bl %1"
12744   [(set_attr "type" "branch")
12745    (set_attr "length" "4")])
12747 (define_insn "*save_gpregs_<mode>_r12"
12748   [(match_parallel 0 "any_parallel_operand"
12749                    [(clobber (reg:P LR_REGNO))
12750                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12751                     (use (reg:P 12))
12752                     (set (match_operand:P 2 "memory_operand" "=m")
12753                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12754   ""
12755   "bl %1"
12756   [(set_attr "type" "branch")
12757    (set_attr "length" "4")])
12759 (define_insn "*save_gpregs_<mode>_r1"
12760   [(match_parallel 0 "any_parallel_operand"
12761                    [(clobber (reg:P LR_REGNO))
12762                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12763                     (use (reg:P 1))
12764                     (set (match_operand:P 2 "memory_operand" "=m")
12765                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12766   ""
12767   "bl %1"
12768   [(set_attr "type" "branch")
12769    (set_attr "length" "4")])
12771 (define_insn "*save_fpregs_<mode>_r11"
12772   [(match_parallel 0 "any_parallel_operand"
12773                    [(clobber (reg:P LR_REGNO))
12774                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12775                     (use (reg:P 11))
12776                     (set (match_operand:DF 2 "memory_operand" "=m")
12777                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12778   ""
12779   "bl %1"
12780   [(set_attr "type" "branch")
12781    (set_attr "length" "4")])
12783 (define_insn "*save_fpregs_<mode>_r12"
12784   [(match_parallel 0 "any_parallel_operand"
12785                    [(clobber (reg:P LR_REGNO))
12786                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12787                     (use (reg:P 12))
12788                     (set (match_operand:DF 2 "memory_operand" "=m")
12789                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12790   ""
12791   "bl %1"
12792   [(set_attr "type" "branch")
12793    (set_attr "length" "4")])
12795 (define_insn "*save_fpregs_<mode>_r1"
12796   [(match_parallel 0 "any_parallel_operand"
12797                    [(clobber (reg:P LR_REGNO))
12798                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12799                     (use (reg:P 1))
12800                     (set (match_operand:DF 2 "memory_operand" "=m")
12801                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12802   ""
12803   "bl %1"
12804   [(set_attr "type" "branch")
12805    (set_attr "length" "4")])
12807 ; This is to explain that changes to the stack pointer should
12808 ; not be moved over loads from or stores to stack memory.
12809 (define_insn "stack_tie"
12810   [(match_parallel 0 "tie_operand"
12811                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12812   ""
12813   ""
12814   [(set_attr "length" "0")])
12816 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12817 ; stay behind all restores from the stack, it cannot be reordered to before
12818 ; one.  See PR77687.  This insn is an add or mr, and a stack_tie on the
12819 ; operands of that.
12820 (define_insn "stack_restore_tie"
12821   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12822         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12823                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12824    (set (mem:BLK (match_dup 0)) (const_int 0))
12825    (set (mem:BLK (match_dup 1)) (const_int 0))]
12826   "TARGET_32BIT"
12827   "@
12828    mr %0,%1
12829    add%I2 %0,%1,%2"
12830   [(set_attr "type" "*,add")])
12832 (define_expand "epilogue"
12833   [(use (const_int 0))]
12834   ""
12836   if (!TARGET_SCHED_PROLOG)
12837     emit_insn (gen_blockage ());
12838   rs6000_emit_epilogue (FALSE);
12839   DONE;
12842 ; On some processors, doing the mtcrf one CC register at a time is
12843 ; faster (like on the 604e).  On others, doing them all at once is
12844 ; faster; for instance, on the 601 and 750.
12846 (define_expand "movsi_to_cr_one"
12847   [(set (match_operand:CC 0 "cc_reg_operand" "")
12848         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12849                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12850   ""
12851   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12853 (define_insn "*movsi_to_cr"
12854   [(match_parallel 0 "mtcrf_operation"
12855                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12856                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12857                                      (match_operand 3 "immediate_operand" "n")]
12858                                     UNSPEC_MOVESI_TO_CR))])]
12859  ""
12860  "*
12862   int mask = 0;
12863   int i;
12864   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12865     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12866   operands[4] = GEN_INT (mask);
12867   return \"mtcrf %4,%2\";
12869   [(set_attr "type" "mtcr")])
12871 (define_insn "*mtcrfsi"
12872   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12873         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12874                     (match_operand 2 "immediate_operand" "n")]
12875                    UNSPEC_MOVESI_TO_CR))]
12876   "GET_CODE (operands[0]) == REG
12877    && CR_REGNO_P (REGNO (operands[0]))
12878    && GET_CODE (operands[2]) == CONST_INT
12879    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12880   "mtcrf %R0,%1"
12881   [(set_attr "type" "mtcr")])
12883 ; The load-multiple instructions have similar properties.
12884 ; Note that "load_multiple" is a name known to the machine-independent
12885 ; code that actually corresponds to the PowerPC load-string.
12887 (define_insn "*lmw"
12888   [(match_parallel 0 "lmw_operation"
12889                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12890                          (match_operand:SI 2 "memory_operand" "m"))])]
12891   "TARGET_MULTIPLE"
12892   "lmw %1,%2"
12893   [(set_attr "type" "load")
12894    (set_attr "update" "yes")
12895    (set_attr "indexed" "yes")
12896    (set_attr "cell_micro" "always")])
12898 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12899 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12901 ; The following comment applies to:
12902 ;     save_gpregs_*
12903 ;     save_fpregs_*
12904 ;     restore_gpregs*
12905 ;     return_and_restore_gpregs*
12906 ;     return_and_restore_fpregs*
12907 ;     return_and_restore_fpregs_aix*
12909 ; The out-of-line save / restore functions expects one input argument.
12910 ; Since those are not standard call_insn's, we must avoid using
12911 ; MATCH_OPERAND for that argument. That way the register rename
12912 ; optimization will not try to rename this register.
12913 ; Each pattern is repeated for each possible register number used in 
12914 ; various ABIs (r11, r1, and for some functions r12)
12916 (define_insn "*restore_gpregs_<mode>_r11"
12917  [(match_parallel 0 "any_parallel_operand"
12918                   [(clobber (reg:P LR_REGNO))
12919                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12920                    (use (reg:P 11))
12921                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12922                         (match_operand:P 3 "memory_operand" "m"))])]
12923  ""
12924  "bl %1"
12925  [(set_attr "type" "branch")
12926   (set_attr "length" "4")])
12928 (define_insn "*restore_gpregs_<mode>_r12"
12929  [(match_parallel 0 "any_parallel_operand"
12930                   [(clobber (reg:P LR_REGNO))
12931                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12932                    (use (reg:P 12))
12933                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12934                         (match_operand:P 3 "memory_operand" "m"))])]
12935  ""
12936  "bl %1"
12937  [(set_attr "type" "branch")
12938   (set_attr "length" "4")])
12940 (define_insn "*restore_gpregs_<mode>_r1"
12941  [(match_parallel 0 "any_parallel_operand"
12942                   [(clobber (reg:P LR_REGNO))
12943                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12944                    (use (reg:P 1))
12945                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12946                         (match_operand:P 3 "memory_operand" "m"))])]
12947  ""
12948  "bl %1"
12949  [(set_attr "type" "branch")
12950   (set_attr "length" "4")])
12952 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12953  [(match_parallel 0 "any_parallel_operand"
12954                   [(return)
12955                    (clobber (reg:P LR_REGNO))
12956                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12957                    (use (reg:P 11))
12958                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12959                         (match_operand:P 3 "memory_operand" "m"))])]
12960  ""
12961  "b %1"
12962  [(set_attr "type" "branch")
12963   (set_attr "length" "4")])
12965 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12966  [(match_parallel 0 "any_parallel_operand"
12967                   [(return)
12968                    (clobber (reg:P LR_REGNO))
12969                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12970                    (use (reg:P 12))
12971                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12972                         (match_operand:P 3 "memory_operand" "m"))])]
12973  ""
12974  "b %1"
12975  [(set_attr "type" "branch")
12976   (set_attr "length" "4")])
12978 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12979  [(match_parallel 0 "any_parallel_operand"
12980                   [(return)
12981                    (clobber (reg:P LR_REGNO))
12982                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12983                    (use (reg:P 1))
12984                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12985                         (match_operand:P 3 "memory_operand" "m"))])]
12986  ""
12987  "b %1"
12988  [(set_attr "type" "branch")
12989   (set_attr "length" "4")])
12991 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12992  [(match_parallel 0 "any_parallel_operand"
12993                   [(return)
12994                    (clobber (reg:P LR_REGNO))
12995                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12996                    (use (reg:P 11))
12997                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12998                         (match_operand:DF 3 "memory_operand" "m"))])]
12999  ""
13000  "b %1"
13001  [(set_attr "type" "branch")
13002   (set_attr "length" "4")])
13004 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13005  [(match_parallel 0 "any_parallel_operand"
13006                   [(return)
13007                    (clobber (reg:P LR_REGNO))
13008                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13009                    (use (reg:P 12))
13010                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13011                         (match_operand:DF 3 "memory_operand" "m"))])]
13012  ""
13013  "b %1"
13014  [(set_attr "type" "branch")
13015   (set_attr "length" "4")])
13017 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13018  [(match_parallel 0 "any_parallel_operand"
13019                   [(return)
13020                    (clobber (reg:P LR_REGNO))
13021                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13022                    (use (reg:P 1))
13023                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13024                         (match_operand:DF 3 "memory_operand" "m"))])]
13025  ""
13026  "b %1"
13027  [(set_attr "type" "branch")
13028   (set_attr "length" "4")])
13030 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13031  [(match_parallel 0 "any_parallel_operand"
13032                   [(return)
13033                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13034                    (use (reg:P 11))
13035                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13036                         (match_operand:DF 3 "memory_operand" "m"))])]
13037  ""
13038  "b %1"
13039  [(set_attr "type" "branch")
13040   (set_attr "length" "4")])
13042 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13043  [(match_parallel 0 "any_parallel_operand"
13044                   [(return)
13045                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13046                    (use (reg:P 1))
13047                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13048                         (match_operand:DF 3 "memory_operand" "m"))])]
13049  ""
13050  "b %1"
13051  [(set_attr "type" "branch")
13052   (set_attr "length" "4")])
13054 ; This is used in compiling the unwind routines.
13055 (define_expand "eh_return"
13056   [(use (match_operand 0 "general_operand" ""))]
13057   ""
13058   "
13060   if (TARGET_32BIT)
13061     emit_insn (gen_eh_set_lr_si (operands[0]));
13062   else
13063     emit_insn (gen_eh_set_lr_di (operands[0]));
13064   DONE;
13067 ; We can't expand this before we know where the link register is stored.
13068 (define_insn "eh_set_lr_<mode>"
13069   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13070                     UNSPECV_EH_RR)
13071    (clobber (match_scratch:P 1 "=&b"))]
13072   ""
13073   "#")
13075 (define_split
13076   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13077    (clobber (match_scratch 1 ""))]
13078   "reload_completed"
13079   [(const_int 0)]
13080   "
13082   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13083   DONE;
13086 (define_insn "prefetch"
13087   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13088              (match_operand:SI 1 "const_int_operand" "n")
13089              (match_operand:SI 2 "const_int_operand" "n"))]
13090   ""
13091   "*
13093   if (GET_CODE (operands[0]) == REG)
13094     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13095   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13097   [(set_attr "type" "load")])
13099 ;; Handle -fsplit-stack.
13101 (define_expand "split_stack_prologue"
13102   [(const_int 0)]
13103   ""
13105   rs6000_expand_split_stack_prologue ();
13106   DONE;
13109 (define_expand "load_split_stack_limit"
13110   [(set (match_operand 0)
13111         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13112   ""
13114   emit_insn (gen_rtx_SET (operands[0],
13115                           gen_rtx_UNSPEC (Pmode,
13116                                           gen_rtvec (1, const0_rtx),
13117                                           UNSPEC_STACK_CHECK)));
13118   DONE;
13121 (define_insn "load_split_stack_limit_di"
13122   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13123         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13124   "TARGET_64BIT"
13125   "ld %0,-0x7040(13)"
13126   [(set_attr "type" "load")
13127    (set_attr "update" "no")
13128    (set_attr "indexed" "no")])
13130 (define_insn "load_split_stack_limit_si"
13131   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13132         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13133   "!TARGET_64BIT"
13134   "lwz %0,-0x7020(2)"
13135   [(set_attr "type" "load")
13136    (set_attr "update" "no")
13137    (set_attr "indexed" "no")])
13139 ;; A return instruction which the middle-end doesn't see.
13140 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13141 ;; after the call to __morestack.
13142 (define_insn "split_stack_return"
13143   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13144   ""
13145   "blr"
13146   [(set_attr "type" "jmpreg")])
13148 ;; If there are operand 0 bytes available on the stack, jump to
13149 ;; operand 1.
13150 (define_expand "split_stack_space_check"
13151   [(set (match_dup 2)
13152         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13153    (set (match_dup 3)
13154         (minus (reg STACK_POINTER_REGNUM)
13155                (match_operand 0)))
13156    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13157    (set (pc) (if_then_else
13158               (geu (match_dup 4) (const_int 0))
13159               (label_ref (match_operand 1))
13160               (pc)))]
13161   ""
13163   rs6000_split_stack_space_check (operands[0], operands[1]);
13164   DONE;
13167 (define_insn "bpermd_<mode>"
13168   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13169         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13170                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13171   "TARGET_POPCNTD"
13172   "bpermd %0,%1,%2"
13173   [(set_attr "type" "popcnt")])
13176 ;; Builtin fma support.  Handle 
13177 ;; Note that the conditions for expansion are in the FMA_F iterator.
13179 (define_expand "fma<mode>4"
13180   [(set (match_operand:FMA_F 0 "register_operand" "")
13181         (fma:FMA_F
13182           (match_operand:FMA_F 1 "register_operand" "")
13183           (match_operand:FMA_F 2 "register_operand" "")
13184           (match_operand:FMA_F 3 "register_operand" "")))]
13185   ""
13186   "")
13188 (define_insn "*fma<mode>4_fpr"
13189   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13190         (fma:SFDF
13191           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13192           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13193           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13194   "TARGET_<MODE>_FPR"
13195   "@
13196    fmadd<Ftrad> %0,%1,%2,%3
13197    xsmadda<Fvsx> %x0,%x1,%x2
13198    xsmaddm<Fvsx> %x0,%x1,%x3"
13199   [(set_attr "type" "fp")
13200    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13202 ; Altivec only has fma and nfms.
13203 (define_expand "fms<mode>4"
13204   [(set (match_operand:FMA_F 0 "register_operand" "")
13205         (fma:FMA_F
13206           (match_operand:FMA_F 1 "register_operand" "")
13207           (match_operand:FMA_F 2 "register_operand" "")
13208           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
13209   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13210   "")
13212 (define_insn "*fms<mode>4_fpr"
13213   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13214         (fma:SFDF
13215          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13216          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13217          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13218   "TARGET_<MODE>_FPR"
13219   "@
13220    fmsub<Ftrad> %0,%1,%2,%3
13221    xsmsuba<Fvsx> %x0,%x1,%x2
13222    xsmsubm<Fvsx> %x0,%x1,%x3"
13223   [(set_attr "type" "fp")
13224    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13226 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13227 (define_expand "fnma<mode>4"
13228   [(set (match_operand:FMA_F 0 "register_operand" "")
13229         (neg:FMA_F
13230           (fma:FMA_F
13231             (match_operand:FMA_F 1 "register_operand" "")
13232             (match_operand:FMA_F 2 "register_operand" "")
13233             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13234   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13235   "")
13237 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13238 (define_expand "fnms<mode>4"
13239   [(set (match_operand:FMA_F 0 "register_operand" "")
13240         (neg:FMA_F
13241           (fma:FMA_F
13242             (match_operand:FMA_F 1 "register_operand" "")
13243             (match_operand:FMA_F 2 "register_operand" "")
13244             (match_operand:FMA_F 3 "register_operand" ""))))]
13245   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13246   "")
13248 ; Not an official optab name, but used from builtins.
13249 (define_expand "nfma<mode>4"
13250   [(set (match_operand:FMA_F 0 "register_operand" "")
13251         (neg:FMA_F
13252           (fma:FMA_F
13253             (match_operand:FMA_F 1 "register_operand" "")
13254             (match_operand:FMA_F 2 "register_operand" "")
13255             (match_operand:FMA_F 3 "register_operand" ""))))]
13256   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13257   "")
13259 (define_insn "*nfma<mode>4_fpr"
13260   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13261         (neg:SFDF
13262          (fma:SFDF
13263           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13264           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13265           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13266   "TARGET_<MODE>_FPR"
13267   "@
13268    fnmadd<Ftrad> %0,%1,%2,%3
13269    xsnmadda<Fvsx> %x0,%x1,%x2
13270    xsnmaddm<Fvsx> %x0,%x1,%x3"
13271   [(set_attr "type" "fp")
13272    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13274 ; Not an official optab name, but used from builtins.
13275 (define_expand "nfms<mode>4"
13276   [(set (match_operand:FMA_F 0 "register_operand" "")
13277         (neg:FMA_F
13278           (fma:FMA_F
13279             (match_operand:FMA_F 1 "register_operand" "")
13280             (match_operand:FMA_F 2 "register_operand" "")
13281             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13282   ""
13283   "")
13285 (define_insn "*nfmssf4_fpr"
13286   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13287         (neg:SFDF
13288          (fma:SFDF
13289           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13290           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13291           (neg:SFDF
13292            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13293   "TARGET_<MODE>_FPR"
13294   "@
13295    fnmsub<Ftrad> %0,%1,%2,%3
13296    xsnmsuba<Fvsx> %x0,%x1,%x2
13297    xsnmsubm<Fvsx> %x0,%x1,%x3"
13298   [(set_attr "type" "fp")
13299    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13302 (define_expand "rs6000_get_timebase"
13303   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13304   ""
13306   if (TARGET_POWERPC64)
13307     emit_insn (gen_rs6000_mftb_di (operands[0]));
13308   else
13309     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13310   DONE;
13313 (define_insn "rs6000_get_timebase_ppc32"
13314   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13315         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13316    (clobber (match_scratch:SI 1 "=r"))
13317    (clobber (match_scratch:CC 2 "=y"))]
13318   "!TARGET_POWERPC64"
13320   if (WORDS_BIG_ENDIAN)
13321     if (TARGET_MFCRF)
13322       {
13323         return "mfspr %0,269\;"
13324                "mfspr %L0,268\;"
13325                "mfspr %1,269\;"
13326                "cmpw %2,%0,%1\;"
13327                "bne- %2,$-16";
13328       }
13329     else
13330       {
13331         return "mftbu %0\;"
13332                "mftb %L0\;"
13333                "mftbu %1\;"
13334                "cmpw %2,%0,%1\;"
13335                "bne- %2,$-16";
13336       }
13337   else
13338     if (TARGET_MFCRF)
13339       {
13340         return "mfspr %L0,269\;"
13341                "mfspr %0,268\;"
13342                "mfspr %1,269\;"
13343                "cmpw %2,%L0,%1\;"
13344                "bne- %2,$-16";
13345       }
13346     else
13347       {
13348         return "mftbu %L0\;"
13349                "mftb %0\;"
13350                "mftbu %1\;"
13351                "cmpw %2,%L0,%1\;"
13352                "bne- %2,$-16";
13353       }
13355   [(set_attr "length" "20")])
13357 (define_insn "rs6000_mftb_<mode>"
13358   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13359         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13360   ""
13362   if (TARGET_MFCRF)
13363     return "mfspr %0,268";
13364   else
13365     return "mftb %0";
13369 (define_insn "rs6000_mffs"
13370   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13371         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13372   "TARGET_HARD_FLOAT && TARGET_FPRS"
13373   "mffs %0")
13375 (define_insn "rs6000_mtfsf"
13376   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13377                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13378                     UNSPECV_MTFSF)]
13379   "TARGET_HARD_FLOAT && TARGET_FPRS"
13380   "mtfsf %0,%1")
13383 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13384 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13385 ;; register that is being loaded.  The fused ops must be physically adjacent.
13387 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13388 ;; before register allocation, and is meant to reduce the lifetime for the
13389 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13390 ;; to use the register that is being load.  The peephole2 then gathers any
13391 ;; other fused possibilities that it can find after register allocation.  If
13392 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13394 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13395 ;; before register allocation, so that we can avoid allocating a temporary base
13396 ;; register that won't be used, and that we try to load into base registers,
13397 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13398 ;; (addis followed by load) even on power8.
13400 (define_split
13401   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13402         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13403   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13404   [(parallel [(set (match_dup 0) (match_dup 2))
13405               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13406               (use (match_dup 3))
13407               (clobber (scratch:DI))])]
13409   operands[2] = fusion_wrap_memory_address (operands[1]);
13410   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13413 (define_insn "*toc_fusionload_<mode>"
13414   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13415         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13416    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13417    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13418    (clobber (match_scratch:DI 3 "=X,&b"))]
13419   "TARGET_TOC_FUSION_INT"
13421   if (base_reg_operand (operands[0], <MODE>mode))
13422     return emit_fusion_gpr_load (operands[0], operands[1]);
13424   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13426   [(set_attr "type" "load")
13427    (set_attr "length" "8")])
13429 (define_insn "*toc_fusionload_di"
13430   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13431         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13432    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13433    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13434    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13435   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13436    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13438   if (base_reg_operand (operands[0], DImode))
13439     return emit_fusion_gpr_load (operands[0], operands[1]);
13441   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13443   [(set_attr "type" "load")
13444    (set_attr "length" "8")])
13447 ;; Find cases where the addis that feeds into a load instruction is either used
13448 ;; once or is the same as the target register, and replace it with the fusion
13449 ;; insn
13451 (define_peephole2
13452   [(set (match_operand:P 0 "base_reg_operand" "")
13453         (match_operand:P 1 "fusion_gpr_addis" ""))
13454    (set (match_operand:INT1 2 "base_reg_operand" "")
13455         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13456   "TARGET_P8_FUSION
13457    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13458                          operands[3])"
13459   [(const_int 0)]
13461   expand_fusion_gpr_load (operands);
13462   DONE;
13465 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13466 ;; reload)
13468 (define_insn "fusion_gpr_load_<mode>"
13469   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13470         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13471                      UNSPEC_FUSION_GPR))]
13472   "TARGET_P8_FUSION"
13474   return emit_fusion_gpr_load (operands[0], operands[1]);
13476   [(set_attr "type" "load")
13477    (set_attr "length" "8")])
13480 ;; ISA 3.0 (power9) fusion support
13481 ;; Merge addis with floating load/store to FPRs (or GPRs).
13482 (define_peephole2
13483   [(set (match_operand:P 0 "base_reg_operand" "")
13484         (match_operand:P 1 "fusion_gpr_addis" ""))
13485    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13486         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13487   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13488    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13489   [(const_int 0)]
13491   expand_fusion_p9_load (operands);
13492   DONE;
13495 (define_peephole2
13496   [(set (match_operand:P 0 "base_reg_operand" "")
13497         (match_operand:P 1 "fusion_gpr_addis" ""))
13498    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13499         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13500   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13501    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13502    && !rtx_equal_p (operands[0], operands[3])"
13503   [(const_int 0)]
13505   expand_fusion_p9_store (operands);
13506   DONE;
13509 (define_peephole2
13510   [(set (match_operand:SDI 0 "int_reg_operand" "")
13511         (match_operand:SDI 1 "upper16_cint_operand" ""))
13512    (set (match_dup 0)
13513         (ior:SDI (match_dup 0)
13514                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13515   "TARGET_P9_FUSION"
13516   [(set (match_dup 0)
13517         (unspec:SDI [(match_dup 1)
13518                      (match_dup 2)] UNSPEC_FUSION_P9))])
13520 (define_peephole2
13521   [(set (match_operand:SDI 0 "int_reg_operand" "")
13522         (match_operand:SDI 1 "upper16_cint_operand" ""))
13523    (set (match_operand:SDI 2 "int_reg_operand" "")
13524         (ior:SDI (match_dup 0)
13525                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13526   "TARGET_P9_FUSION
13527    && !rtx_equal_p (operands[0], operands[2])
13528    && peep2_reg_dead_p (2, operands[0])"
13529   [(set (match_dup 2)
13530         (unspec:SDI [(match_dup 1)
13531                      (match_dup 3)] UNSPEC_FUSION_P9))])
13533 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13534 ;; reload).  Because we want to eventually have secondary_reload generate
13535 ;; these, they have to have a single alternative that gives the register
13536 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13537 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13538   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13539         (unspec:GPR_FUSION
13540          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13541          UNSPEC_FUSION_P9))
13542    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13543   "TARGET_P9_FUSION"
13545   /* This insn is a secondary reload insn, which cannot have alternatives.
13546      If we are not loading up register 0, use the power8 fusion instead.  */
13547   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13548     return emit_fusion_gpr_load (operands[0], operands[1]);
13550   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13552   [(set_attr "type" "load")
13553    (set_attr "length" "8")])
13555 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13556   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13557         (unspec:GPR_FUSION
13558          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13559          UNSPEC_FUSION_P9))
13560    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13561   "TARGET_P9_FUSION"
13563   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13565   [(set_attr "type" "store")
13566    (set_attr "length" "8")])
13568 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13569   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13570         (unspec:FPR_FUSION
13571          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13572          UNSPEC_FUSION_P9))
13573    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13574   "TARGET_P9_FUSION"
13576   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13578   [(set_attr "type" "fpload")
13579    (set_attr "length" "8")])
13581 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13582   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13583         (unspec:FPR_FUSION
13584          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13585          UNSPEC_FUSION_P9))
13586    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13587   "TARGET_P9_FUSION"
13589   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13591   [(set_attr "type" "fpstore")
13592    (set_attr "length" "8")])
13594 (define_insn "*fusion_p9_<mode>_constant"
13595   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13596         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13597                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13598                     UNSPEC_FUSION_P9))] 
13599   "TARGET_P9_FUSION"
13601   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13602   return "ori %0,%0,%2";
13604   [(set_attr "type" "two")
13605    (set_attr "length" "8")])
13608 ;; Miscellaneous ISA 2.06 (power7) instructions
13609 (define_insn "addg6s"
13610   [(set (match_operand:SI 0 "register_operand" "=r")
13611         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13612                     (match_operand:SI 2 "register_operand" "r")]
13613                    UNSPEC_ADDG6S))]
13614   "TARGET_POPCNTD"
13615   "addg6s %0,%1,%2"
13616   [(set_attr "type" "integer")
13617    (set_attr "length" "4")])
13619 (define_insn "cdtbcd"
13620   [(set (match_operand:SI 0 "register_operand" "=r")
13621         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13622                    UNSPEC_CDTBCD))]
13623   "TARGET_POPCNTD"
13624   "cdtbcd %0,%1"
13625   [(set_attr "type" "integer")
13626    (set_attr "length" "4")])
13628 (define_insn "cbcdtd"
13629   [(set (match_operand:SI 0 "register_operand" "=r")
13630         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13631                    UNSPEC_CBCDTD))]
13632   "TARGET_POPCNTD"
13633   "cbcdtd %0,%1"
13634   [(set_attr "type" "integer")
13635    (set_attr "length" "4")])
13637 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13638                                         UNSPEC_DIVEO
13639                                         UNSPEC_DIVEU
13640                                         UNSPEC_DIVEUO])
13642 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13643                              (UNSPEC_DIVEO      "eo")
13644                              (UNSPEC_DIVEU      "eu")
13645                              (UNSPEC_DIVEUO     "euo")])
13647 (define_insn "div<div_extend>_<mode>"
13648   [(set (match_operand:GPR 0 "register_operand" "=r")
13649         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13650                      (match_operand:GPR 2 "register_operand" "r")]
13651                     UNSPEC_DIV_EXTEND))]
13652   "TARGET_POPCNTD"
13653   "div<wd><div_extend> %0,%1,%2"
13654   [(set_attr "type" "div")
13655    (set_attr "size" "<bits>")])
13658 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13660 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13661 (define_mode_attr FP128_64 [(TF "DF")
13662                             (IF "DF")
13663                             (TD "DI")
13664                             (KF "DI")])
13666 (define_expand "unpack<mode>"
13667   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13668         (unspec:<FP128_64>
13669          [(match_operand:FMOVE128 1 "register_operand" "")
13670           (match_operand:QI 2 "const_0_to_1_operand" "")]
13671          UNSPEC_UNPACK_128BIT))]
13672   "FLOAT128_2REG_P (<MODE>mode)"
13673   "")
13675 (define_insn_and_split "unpack<mode>_dm"
13676   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13677         (unspec:<FP128_64>
13678          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13679           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13680          UNSPEC_UNPACK_128BIT))]
13681   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13682   "#"
13683   "&& reload_completed"
13684   [(set (match_dup 0) (match_dup 3))]
13686   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13688   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13689     {
13690       emit_note (NOTE_INSN_DELETED);
13691       DONE;
13692     }
13694   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13696   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13697    (set_attr "length" "4")])
13699 (define_insn_and_split "unpack<mode>_nodm"
13700   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13701         (unspec:<FP128_64>
13702          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13703           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13704          UNSPEC_UNPACK_128BIT))]
13705   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13706   "#"
13707   "&& reload_completed"
13708   [(set (match_dup 0) (match_dup 3))]
13710   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13712   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13713     {
13714       emit_note (NOTE_INSN_DELETED);
13715       DONE;
13716     }
13718   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13720   [(set_attr "type" "fp,fpstore")
13721    (set_attr "length" "4")])
13723 (define_insn_and_split "pack<mode>"
13724   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13725         (unspec:FMOVE128
13726          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13727           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13728          UNSPEC_PACK_128BIT))]
13729   "FLOAT128_2REG_P (<MODE>mode)"
13730   "@
13731    fmr %L0,%2
13732    #"
13733   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13734   [(set (match_dup 3) (match_dup 1))
13735    (set (match_dup 4) (match_dup 2))]
13737   unsigned dest_hi = REGNO (operands[0]);
13738   unsigned dest_lo = dest_hi + 1;
13740   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13741   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13743   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13744   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13746   [(set_attr "type" "fpsimple,fp")
13747    (set_attr "length" "4,8")])
13749 (define_insn "unpack<mode>"
13750   [(set (match_operand:DI 0 "register_operand" "=d,d")
13751         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13752                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13753          UNSPEC_UNPACK_128BIT))]
13754   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13756   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13757     return ASM_COMMENT_START " xxpermdi to same register";
13759   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13760   return "xxpermdi %x0,%x1,%x1,%3";
13762   [(set_attr "type" "vecperm")])
13764 (define_insn "pack<mode>"
13765   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13766         (unspec:FMOVE128_VSX
13767          [(match_operand:DI 1 "register_operand" "d")
13768           (match_operand:DI 2 "register_operand" "d")]
13769          UNSPEC_PACK_128BIT))]
13770   "TARGET_VSX"
13771   "xxpermdi %x0,%x1,%x2,0"
13772   [(set_attr "type" "vecperm")])
13776 ;; ISA 2.08 IEEE 128-bit floating point support.
13778 (define_insn "add<mode>3"
13779   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13780         (plus:IEEE128
13781          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13782          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13783   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13784   "xsaddqp %0,%1,%2"
13785   [(set_attr "type" "vecfloat")
13786    (set_attr "size" "128")])
13788 (define_insn "sub<mode>3"
13789   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13790         (minus:IEEE128
13791          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13792          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13793   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13794   "xssubqp %0,%1,%2"
13795   [(set_attr "type" "vecfloat")
13796    (set_attr "size" "128")])
13798 (define_insn "mul<mode>3"
13799   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13800         (mult:IEEE128
13801          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13802          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13803   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13804   "xsmulqp %0,%1,%2"
13805   [(set_attr "type" "vecfloat")
13806    (set_attr "size" "128")])
13808 (define_insn "div<mode>3"
13809   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13810         (div:IEEE128
13811          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13812          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13813   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13814   "xsdivqp %0,%1,%2"
13815   [(set_attr "type" "vecdiv")
13816    (set_attr "size" "128")])
13818 (define_insn "sqrt<mode>2"
13819   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13820         (sqrt:IEEE128
13821          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13822   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13823    "xssqrtqp %0,%1"
13824   [(set_attr "type" "vecdiv")
13825    (set_attr "size" "128")])
13827 (define_expand "copysign<mode>3"
13828   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13829    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13830    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13831   "FLOAT128_IEEE_P (<MODE>mode)"
13833   if (TARGET_FLOAT128_HW)
13834     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13835                                          operands[2]));
13836   else
13837     {
13838       rtx tmp = gen_reg_rtx (<MODE>mode);
13839       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13840                                            operands[2], tmp));
13841     }
13842   DONE;
13845 (define_insn "copysign<mode>3_hard"
13846   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13847         (unspec:IEEE128
13848          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13849           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13850          UNSPEC_COPYSIGN))]
13851   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13852    "xscpsgnqp %0,%2,%1"
13853   [(set_attr "type" "vecmove")
13854    (set_attr "size" "128")])
13856 (define_insn "copysign<mode>3_soft"
13857   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13858         (unspec:IEEE128
13859          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13860           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13861           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13862          UNSPEC_COPYSIGN))]
13863   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13864    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13865   [(set_attr "type" "veccomplex")
13866    (set_attr "length" "8")])
13868 (define_insn "neg<mode>2_hw"
13869   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13870         (neg:IEEE128
13871          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13872   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13873   "xsnegqp %0,%1"
13874   [(set_attr "type" "vecmove")
13875    (set_attr "size" "128")])
13878 (define_insn "abs<mode>2_hw"
13879   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13880         (abs:IEEE128
13881          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13882   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13883   "xsabsqp %0,%1"
13884   [(set_attr "type" "vecmove")
13885    (set_attr "size" "128")])
13888 (define_insn "*nabs<mode>2_hw"
13889   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13890         (neg:IEEE128
13891          (abs:IEEE128
13892           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13893   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13894   "xsnabsqp %0,%1"
13895   [(set_attr "type" "vecmove")
13896    (set_attr "size" "128")])
13898 ;; Initially don't worry about doing fusion
13899 (define_insn "*fma<mode>4_hw"
13900   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13901         (fma:IEEE128
13902          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13903          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13904          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13905   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13906   "xsmaddqp %0,%1,%2"
13907   [(set_attr "type" "vecfloat")
13908    (set_attr "size" "128")])
13910 (define_insn "*fms<mode>4_hw"
13911   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13912         (fma:IEEE128
13913          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13914          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13915          (neg:IEEE128
13916           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13917   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13918   "xsmsubqp %0,%1,%2"
13919   [(set_attr "type" "vecfloat")
13920    (set_attr "size" "128")])
13922 (define_insn "*nfma<mode>4_hw"
13923   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13924         (neg:IEEE128
13925          (fma:IEEE128
13926           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13927           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13928           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13929   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13930   "xsnmaddqp %0,%1,%2"
13931   [(set_attr "type" "vecfloat")
13932    (set_attr "size" "128")])
13934 (define_insn "*nfms<mode>4_hw"
13935   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13936         (neg:IEEE128
13937          (fma:IEEE128
13938           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13939           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13940           (neg:IEEE128
13941            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13942   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13943   "xsnmsubqp %0,%1,%2"
13944   [(set_attr "type" "vecfloat")
13945    (set_attr "size" "128")])
13947 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13948   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13949         (float_extend:IEEE128
13950          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13951   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13952   "xscvdpqp %0,%1"
13953   [(set_attr "type" "vecfloat")
13954    (set_attr "size" "128")])
13956 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13957 ;; point is a simple copy.
13958 (define_insn_and_split "extendkftf2"
13959   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13960         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13961   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13962   "@
13963    #
13964    xxlor %x0,%x1,%x1"
13965   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13966   [(const_int 0)]
13968   emit_note (NOTE_INSN_DELETED);
13969   DONE;
13971   [(set_attr "type" "*,veclogical")
13972    (set_attr "length" "0,4")])
13974 (define_insn_and_split "trunctfkf2"
13975   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13976         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13977   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13978   "@
13979    #
13980    xxlor %x0,%x1,%x1"
13981   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13982   [(const_int 0)]
13984   emit_note (NOTE_INSN_DELETED);
13985   DONE;
13987   [(set_attr "type" "*,veclogical")
13988    (set_attr "length" "0,4")])
13990 (define_insn "trunc<mode>df2_hw"
13991   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13992         (float_truncate:DF
13993          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13994   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13995   "xscvqpdp %0,%1"
13996   [(set_attr "type" "vecfloat")
13997    (set_attr "size" "128")])
13999 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14000 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14001 ;; conversion
14002 (define_insn_and_split "trunc<mode>sf2_hw"
14003   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14004         (float_truncate:SF
14005          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14006    (clobber (match_scratch:DF 2 "=v"))]
14007   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14008   "#"
14009   "&& 1"
14010   [(set (match_dup 2)
14011         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14012    (set (match_dup 0)
14013         (float_truncate:SF (match_dup 2)))]
14015   if (GET_CODE (operands[2]) == SCRATCH)
14016     operands[2] = gen_reg_rtx (DFmode);
14018   [(set_attr "type" "vecfloat")
14019    (set_attr "length" "8")])
14021 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
14022 ;; allowed in the traditional floating point registers. Use V2DImode so that
14023 ;; we can get a value in an Altivec register.
14025 (define_insn_and_split "fix<uns>_<mode>si2_hw"
14026   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
14027         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
14028    (clobber (match_scratch:V2DI 2 "=v,v"))]
14029   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14030   "#"
14031   "&& 1"
14032   [(pc)]
14034   convert_float128_to_int (operands, <CODE>);
14035   DONE;
14037   [(set_attr "length" "8")
14038    (set_attr "type" "mftgpr,fpstore")])
14040 (define_insn_and_split "fix<uns>_<mode>di2_hw"
14041   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
14042         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
14043    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14044   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14045   "#"
14046   "&& 1"
14047   [(pc)]
14049   convert_float128_to_int (operands, <CODE>);
14050   DONE;
14052   [(set_attr "length" "8")
14053    (set_attr "type" "mftgpr,vecsimple,fpstore")])
14055 (define_insn_and_split "float<uns>_<mode>si2_hw"
14056   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
14057         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
14058    (clobber (match_scratch:V2DI 2 "=v,v"))]
14059   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14060   "#"
14061   "&& 1"
14062   [(pc)]
14064   convert_int_to_float128 (operands, <CODE>);
14065   DONE;
14067   [(set_attr "length" "8")
14068    (set_attr "type" "vecfloat")])
14070 (define_insn_and_split "float<uns>_<mode>di2_hw"
14071   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14072         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
14073    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14074   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14075   "#"
14076   "&& 1"
14077   [(pc)]
14079   convert_int_to_float128 (operands, <CODE>);
14080   DONE;
14082   [(set_attr "length" "8")
14083    (set_attr "type" "vecfloat")])
14085 ;; Integer conversion instructions, using V2DImode to get an Altivec register
14086 (define_insn "*xscvqp<su>wz_<mode>"
14087   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14088         (unspec:V2DI
14089          [(any_fix:SI
14090            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14091          UNSPEC_IEEE128_CONVERT))]
14092   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14093   "xscvqp<su>wz %0,%1"
14094   [(set_attr "type" "vecfloat")
14095    (set_attr "size" "128")])
14097 (define_insn "*xscvqp<su>dz_<mode>"
14098   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14099         (unspec:V2DI
14100          [(any_fix:DI
14101            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14102          UNSPEC_IEEE128_CONVERT))]
14103   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14104   "xscvqp<su>dz %0,%1"
14105   [(set_attr "type" "vecfloat")
14106    (set_attr "size" "128")])
14108 (define_insn "*xscv<su>dqp_<mode>"
14109   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14110         (any_float:IEEE128
14111          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
14112                     UNSPEC_IEEE128_CONVERT)))]
14113   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14114   "xscv<su>dqp %0,%1"
14115   [(set_attr "type" "vecfloat")
14116    (set_attr "size" "128")])
14118 (define_insn "*ieee128_mfvsrd_64bit"
14119   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
14120         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
14121                    UNSPEC_IEEE128_MOVE))]
14122   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14123   "@
14124    mfvsrd %0,%x1
14125    stxsdx %x1,%y0
14126    xxlor %x0,%x1,%x1"
14127   [(set_attr "type" "mftgpr,fpstore,veclogical")])
14130 (define_insn "*ieee128_mfvsrd_32bit"
14131   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
14132         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14133                    UNSPEC_IEEE128_MOVE))]
14134   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14135   "@
14136    stxsdx %x1,%y0
14137    xxlor %x0,%x1,%x1"
14138   [(set_attr "type" "fpstore,veclogical")])
14140 (define_insn "*ieee128_mfvsrwz"
14141   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
14142         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14143                    UNSPEC_IEEE128_MOVE))]
14144   "TARGET_FLOAT128_HW"
14145   "@
14146    mfvsrwz %0,%x1
14147    stxsiwx %x1,%y0"
14148   [(set_attr "type" "mftgpr,fpstore")])
14150 ;; 0 says do sign-extension, 1 says zero-extension
14151 (define_insn "*ieee128_mtvsrw"
14152   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
14153         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
14154                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
14155                      UNSPEC_IEEE128_MOVE))]
14156   "TARGET_FLOAT128_HW"
14157   "@
14158    mtvsrwa %x0,%1
14159    lxsiwax %x0,%y1
14160    mtvsrwz %x0,%1
14161    lxsiwzx %x0,%y1"
14162   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
14165 (define_insn "*ieee128_mtvsrd_64bit"
14166   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
14167         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
14168                      UNSPEC_IEEE128_MOVE))]
14169   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14170   "@
14171    mtvsrd %x0,%1
14172    lxsdx %x0,%y1
14173    xxlor %x0,%x1,%x1"
14174   [(set_attr "type" "mffgpr,fpload,veclogical")])
14176 (define_insn "*ieee128_mtvsrd_32bit"
14177   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
14178         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
14179                      UNSPEC_IEEE128_MOVE))]
14180   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14181   "@
14182    lxsdx %x0,%y1
14183    xxlor %x0,%x1,%x1"
14184   [(set_attr "type" "fpload,veclogical")])
14186 ;; IEEE 128-bit instructions with round to odd semantics
14187 (define_insn "*trunc<mode>df2_odd"
14188   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14189         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14190                    UNSPEC_ROUND_TO_ODD))]
14191   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14192   "xscvqpdpo %0,%1"
14193   [(set_attr "type" "vecfloat")
14194    (set_attr "size" "128")])
14196 ;; IEEE 128-bit comparisons
14197 (define_insn "*cmp<mode>_hw"
14198   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14199         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14200                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14201   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14202    "xscmpuqp %0,%1,%2"
14203   [(set_attr "type" "veccmp")
14204    (set_attr "size" "128")])
14208 (include "sync.md")
14209 (include "vector.md")
14210 (include "vsx.md")
14211 (include "altivec.md")
14212 (include "spe.md")
14213 (include "dfp.md")
14214 (include "paired.md")
14215 (include "crypto.md")
14216 (include "htm.md")