PR target/79197
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobbb0927ffb2f6e65c9deed6a679447cadcc693a20
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2017 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_CMPB
121    UNSPEC_FCTIW
122    UNSPEC_FCTID
123    UNSPEC_LFIWAX
124    UNSPEC_LFIWZX
125    UNSPEC_FCTIWUZ
126    UNSPEC_NOP
127    UNSPEC_GRP_END_NOP
128    UNSPEC_P8V_FMRGOW
129    UNSPEC_P8V_MTVSRWZ
130    UNSPEC_P8V_RELOAD_FROM_GPR
131    UNSPEC_P8V_MTVSRD
132    UNSPEC_P8V_XXPERMDI
133    UNSPEC_P8V_RELOAD_FROM_VSX
134    UNSPEC_ADDG6S
135    UNSPEC_CDTBCD
136    UNSPEC_CBCDTD
137    UNSPEC_DIVE
138    UNSPEC_DIVEO
139    UNSPEC_DIVEU
140    UNSPEC_DIVEUO
141    UNSPEC_UNPACK_128BIT
142    UNSPEC_PACK_128BIT
143    UNSPEC_LSQ
144    UNSPEC_FUSION_GPR
145    UNSPEC_STACK_CHECK
146    UNSPEC_FUSION_P9
147    UNSPEC_FUSION_ADDIS
148    UNSPEC_ROUND_TO_ODD
149    UNSPEC_SIGNBIT
150    UNSPEC_SF_FROM_SI
151    UNSPEC_SI_FROM_SF
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 ; Iterator for ISA 3.0 supported floating point types
521 (define_mode_iterator FP_ISA3 [SF DF])
523 ; SF/DF suffix for traditional floating instructions
524 (define_mode_attr Ftrad         [(SF "s") (DF "")])
526 ; SF/DF suffix for VSX instructions
527 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
529 ; SF/DF constraint for arithmetic on traditional floating point registers
530 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
532 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
533 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
534 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
535 ; format.
536 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
538 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
539 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
540 ; instructions added in ISA 2.07 (power8)
541 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
543 ; SF/DF constraint for arithmetic on altivec registers
544 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
546 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
547 (define_mode_attr Fs            [(SF "s")  (DF "d")])
549 ; FRE/FRES support
550 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
551 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
553 ; Conditional returns.
554 (define_code_iterator any_return [return simple_return])
555 (define_code_attr return_pred [(return "direct_return ()")
556                                (simple_return "1")])
557 (define_code_attr return_str [(return "") (simple_return "simple_")])
559 ; Logical operators.
560 (define_code_iterator iorxor            [ior xor])
561 (define_code_iterator and_ior_xor       [and ior xor])
563 ; Signed/unsigned variants of ops.
564 (define_code_iterator any_extend        [sign_extend zero_extend])
565 (define_code_iterator any_fix           [fix unsigned_fix])
566 (define_code_iterator any_float         [float unsigned_float])
568 (define_code_attr u  [(sign_extend      "")
569                       (zero_extend      "u")])
571 (define_code_attr su [(sign_extend      "s")
572                       (zero_extend      "u")
573                       (fix              "s")
574                       (unsigned_fix     "s")
575                       (float            "s")
576                       (unsigned_float   "u")])
578 (define_code_attr az [(sign_extend      "a")
579                       (zero_extend      "z")
580                       (fix              "a")
581                       (unsigned_fix     "z")
582                       (float            "a")
583                       (unsigned_float   "z")])
585 (define_code_attr uns [(fix             "")
586                        (unsigned_fix    "uns")
587                        (float           "")
588                        (unsigned_float  "uns")])
590 ; Various instructions that come in SI and DI forms.
591 ; A generic w/d attribute, for things like cmpw/cmpd.
592 (define_mode_attr wd [(QI    "b")
593                       (HI    "h")
594                       (SI    "w")
595                       (DI    "d")
596                       (V16QI "b")
597                       (V8HI  "h")
598                       (V4SI  "w")
599                       (V2DI  "d")
600                       (V1TI  "q")
601                       (TI    "q")])
603 ;; How many bits in this mode?
604 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
606 ; DImode bits
607 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
609 ;; ISEL/ISEL64 target selection
610 (define_mode_attr sel [(SI "") (DI "64")])
612 ;; Bitmask for shift instructions
613 (define_mode_attr hH [(SI "h") (DI "H")])
615 ;; A mode twice the size of the given mode
616 (define_mode_attr dmode [(SI "di") (DI "ti")])
617 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
619 ;; Suffix for reload patterns
620 (define_mode_attr ptrsize [(SI "32bit")
621                            (DI "64bit")])
623 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
624                             (DI "TARGET_64BIT")])
626 (define_mode_attr mptrsize [(SI "si")
627                             (DI "di")])
629 (define_mode_attr ptrload [(SI "lwz")
630                            (DI "ld")])
632 (define_mode_attr ptrm [(SI "m")
633                         (DI "Y")])
635 (define_mode_attr rreg [(SF   "f")
636                         (DF   "ws")
637                         (TF   "f")
638                         (TD   "f")
639                         (V4SF "wf")
640                         (V2DF "wd")])
642 (define_mode_attr rreg2 [(SF   "f")
643                          (DF   "d")])
645 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
646                                  (DF "TARGET_FCFID")])
648 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
649                                 (DF "TARGET_E500_DOUBLE")])
651 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
652                                 (DF "TARGET_DOUBLE_FLOAT")])
654 ;; Mode iterator for logical operations on 128-bit types
655 (define_mode_iterator BOOL_128          [TI
656                                          PTI
657                                          (V16QI "TARGET_ALTIVEC")
658                                          (V8HI  "TARGET_ALTIVEC")
659                                          (V4SI  "TARGET_ALTIVEC")
660                                          (V4SF  "TARGET_ALTIVEC")
661                                          (V2DI  "TARGET_ALTIVEC")
662                                          (V2DF  "TARGET_ALTIVEC")
663                                          (V1TI  "TARGET_ALTIVEC")])
665 ;; For the GPRs we use 3 constraints for register outputs, two that are the
666 ;; same as the output register, and a third where the output register is an
667 ;; early clobber, so we don't have to deal with register overlaps.  For the
668 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
669 ;; either.
671 ;; Mode attribute for boolean operation register constraints for output
672 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
673                                          (PTI   "&r,r,r")
674                                          (V16QI "wa,v,&?r,?r,?r")
675                                          (V8HI  "wa,v,&?r,?r,?r")
676                                          (V4SI  "wa,v,&?r,?r,?r")
677                                          (V4SF  "wa,v,&?r,?r,?r")
678                                          (V2DI  "wa,v,&?r,?r,?r")
679                                          (V2DF  "wa,v,&?r,?r,?r")
680                                          (V1TI  "wa,v,&?r,?r,?r")])
682 ;; Mode attribute for boolean operation register constraints for operand1
683 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
684                                          (PTI   "r,0,r")
685                                          (V16QI "wa,v,r,0,r")
686                                          (V8HI  "wa,v,r,0,r")
687                                          (V4SI  "wa,v,r,0,r")
688                                          (V4SF  "wa,v,r,0,r")
689                                          (V2DI  "wa,v,r,0,r")
690                                          (V2DF  "wa,v,r,0,r")
691                                          (V1TI  "wa,v,r,0,r")])
693 ;; Mode attribute for boolean operation register constraints for operand2
694 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
695                                          (PTI   "r,r,0")
696                                          (V16QI "wa,v,r,r,0")
697                                          (V8HI  "wa,v,r,r,0")
698                                          (V4SI  "wa,v,r,r,0")
699                                          (V4SF  "wa,v,r,r,0")
700                                          (V2DI  "wa,v,r,r,0")
701                                          (V2DF  "wa,v,r,r,0")
702                                          (V1TI  "wa,v,r,r,0")])
704 ;; Mode attribute for boolean operation register constraints for operand1
705 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
706 ;; is used for operand1 or operand2
707 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
708                                          (PTI   "r,0,0")
709                                          (V16QI "wa,v,r,0,0")
710                                          (V8HI  "wa,v,r,0,0")
711                                          (V4SI  "wa,v,r,0,0")
712                                          (V4SF  "wa,v,r,0,0")
713                                          (V2DI  "wa,v,r,0,0")
714                                          (V2DF  "wa,v,r,0,0")
715                                          (V1TI  "wa,v,r,0,0")])
717 ;; Reload iterator for creating the function to allocate a base register to
718 ;; supplement addressing modes.
719 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
720                               SF SD SI DF DD DI TI PTI KF IF TF])
722 ;; Iterate over smin, smax
723 (define_code_iterator fp_minmax [smin smax])
725 (define_code_attr     minmax    [(smin "min")
726                                  (smax "max")])
728 (define_code_attr     SMINMAX   [(smin "SMIN")
729                                  (smax "SMAX")])
732 ;; Start with fixed-point load and store insns.  Here we put only the more
733 ;; complex forms.  Basic data transfer is done later.
735 (define_insn "zero_extendqi<mode>2"
736   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
737         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
738   ""
739   "@
740    lbz%U1%X1 %0,%1
741    rlwinm %0,%1,0,0xff
742    lxsibzx %x0,%y1
743    vextractub %0,%1,7"
744   [(set_attr "type" "load,shift,fpload,vecperm")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot"
747   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
749                     (const_int 0)))
750    (clobber (match_scratch:EXTQI 0 "=r,r"))]
751   "rs6000_gen_cell_microcode"
752   "@
753    andi. %0,%1,0xff
754    #"
755   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
756   [(set (match_dup 0)
757         (zero_extend:EXTQI (match_dup 1)))
758    (set (match_dup 2)
759         (compare:CC (match_dup 0)
760                     (const_int 0)))]
761   ""
762   [(set_attr "type" "logical")
763    (set_attr "dot" "yes")
764    (set_attr "length" "4,8")])
766 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
767   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
769                     (const_int 0)))
770    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
771         (zero_extend:EXTQI (match_dup 1)))]
772   "rs6000_gen_cell_microcode"
773   "@
774    andi. %0,%1,0xff
775    #"
776   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
777   [(set (match_dup 0)
778         (zero_extend:EXTQI (match_dup 1)))
779    (set (match_dup 2)
780         (compare:CC (match_dup 0)
781                     (const_int 0)))]
782   ""
783   [(set_attr "type" "logical")
784    (set_attr "dot" "yes")
785    (set_attr "length" "4,8")])
788 (define_insn "zero_extendhi<mode>2"
789   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
790         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
791   ""
792   "@
793    lhz%U1%X1 %0,%1
794    rlwinm %0,%1,0,0xffff
795    lxsihzx %x0,%y1
796    vextractuh %0,%1,6"
797   [(set_attr "type" "load,shift,fpload,vecperm")])
799 (define_insn_and_split "*zero_extendhi<mode>2_dot"
800   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
801         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
802                     (const_int 0)))
803    (clobber (match_scratch:EXTHI 0 "=r,r"))]
804   "rs6000_gen_cell_microcode"
805   "@
806    andi. %0,%1,0xffff
807    #"
808   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
809   [(set (match_dup 0)
810         (zero_extend:EXTHI (match_dup 1)))
811    (set (match_dup 2)
812         (compare:CC (match_dup 0)
813                     (const_int 0)))]
814   ""
815   [(set_attr "type" "logical")
816    (set_attr "dot" "yes")
817    (set_attr "length" "4,8")])
819 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
820   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
821         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
822                     (const_int 0)))
823    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
824         (zero_extend:EXTHI (match_dup 1)))]
825   "rs6000_gen_cell_microcode"
826   "@
827    andi. %0,%1,0xffff
828    #"
829   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
830   [(set (match_dup 0)
831         (zero_extend:EXTHI (match_dup 1)))
832    (set (match_dup 2)
833         (compare:CC (match_dup 0)
834                     (const_int 0)))]
835   ""
836   [(set_attr "type" "logical")
837    (set_attr "dot" "yes")
838    (set_attr "length" "4,8")])
841 (define_insn "zero_extendsi<mode>2"
842   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
843         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
844   ""
845   "@
846    lwz%U1%X1 %0,%1
847    rldicl %0,%1,0,32
848    lfiwzx %0,%y1
849    lxsiwzx %x0,%y1
850    mtvsrwz %x0,%1
851    mfvsrwz %0,%x1
852    xxextractuw %x0,%x1,4"
853   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
855 (define_insn_and_split "*zero_extendsi<mode>2_dot"
856   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
857         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
858                     (const_int 0)))
859    (clobber (match_scratch:EXTSI 0 "=r,r"))]
860   "rs6000_gen_cell_microcode"
861   "@
862    rldicl. %0,%1,0,32
863    #"
864   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
865   [(set (match_dup 0)
866         (zero_extend:DI (match_dup 1)))
867    (set (match_dup 2)
868         (compare:CC (match_dup 0)
869                     (const_int 0)))]
870   ""
871   [(set_attr "type" "shift")
872    (set_attr "dot" "yes")
873    (set_attr "length" "4,8")])
875 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
876   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
877         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
878                     (const_int 0)))
879    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
880         (zero_extend:EXTSI (match_dup 1)))]
881   "rs6000_gen_cell_microcode"
882   "@
883    rldicl. %0,%1,0,32
884    #"
885   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
886   [(set (match_dup 0)
887         (zero_extend:EXTSI (match_dup 1)))
888    (set (match_dup 2)
889         (compare:CC (match_dup 0)
890                     (const_int 0)))]
891   ""
892   [(set_attr "type" "shift")
893    (set_attr "dot" "yes")
894    (set_attr "length" "4,8")])
897 (define_insn "extendqi<mode>2"
898   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
899         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
900   ""
901   "@
902    extsb %0,%1
903    vextsb2d %0,%1"
904   [(set_attr "type" "exts,vecperm")])
906 (define_insn_and_split "*extendqi<mode>2_dot"
907   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
909                     (const_int 0)))
910    (clobber (match_scratch:EXTQI 0 "=r,r"))]
911   "rs6000_gen_cell_microcode"
912   "@
913    extsb. %0,%1
914    #"
915   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
916   [(set (match_dup 0)
917         (sign_extend:EXTQI (match_dup 1)))
918    (set (match_dup 2)
919         (compare:CC (match_dup 0)
920                     (const_int 0)))]
921   ""
922   [(set_attr "type" "exts")
923    (set_attr "dot" "yes")
924    (set_attr "length" "4,8")])
926 (define_insn_and_split "*extendqi<mode>2_dot2"
927   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
928         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
929                     (const_int 0)))
930    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
931         (sign_extend:EXTQI (match_dup 1)))]
932   "rs6000_gen_cell_microcode"
933   "@
934    extsb. %0,%1
935    #"
936   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
937   [(set (match_dup 0)
938         (sign_extend:EXTQI (match_dup 1)))
939    (set (match_dup 2)
940         (compare:CC (match_dup 0)
941                     (const_int 0)))]
942   ""
943   [(set_attr "type" "exts")
944    (set_attr "dot" "yes")
945    (set_attr "length" "4,8")])
948 (define_expand "extendhi<mode>2"
949   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
950         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
951   ""
952   "")
954 (define_insn "*extendhi<mode>2"
955   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
956         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
957   "rs6000_gen_cell_microcode"
958   "@
959    lha%U1%X1 %0,%1
960    extsh %0,%1
961    #
962    vextsh2d %0,%1"
963   [(set_attr "type" "load,exts,fpload,vecperm")
964    (set_attr "sign_extend" "yes")
965    (set_attr "length" "4,4,8,4")])
967 (define_split
968   [(set (match_operand:EXTHI 0 "altivec_register_operand")
969         (sign_extend:EXTHI
970          (match_operand:HI 1 "indexed_or_indirect_operand")))]
971   "TARGET_P9_VECTOR && reload_completed"
972   [(set (match_dup 2)
973         (match_dup 1))
974    (set (match_dup 0)
975         (sign_extend:EXTHI (match_dup 2)))]
977   operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
980 (define_insn "*extendhi<mode>2_noload"
981   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
982         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
983   "!rs6000_gen_cell_microcode"
984   "extsh %0,%1"
985   [(set_attr "type" "exts")])
987 (define_insn_and_split "*extendhi<mode>2_dot"
988   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
989         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
990                     (const_int 0)))
991    (clobber (match_scratch:EXTHI 0 "=r,r"))]
992   "rs6000_gen_cell_microcode"
993   "@
994    extsh. %0,%1
995    #"
996   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
997   [(set (match_dup 0)
998         (sign_extend:EXTHI (match_dup 1)))
999    (set (match_dup 2)
1000         (compare:CC (match_dup 0)
1001                     (const_int 0)))]
1002   ""
1003   [(set_attr "type" "exts")
1004    (set_attr "dot" "yes")
1005    (set_attr "length" "4,8")])
1007 (define_insn_and_split "*extendhi<mode>2_dot2"
1008   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1009         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1010                     (const_int 0)))
1011    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1012         (sign_extend:EXTHI (match_dup 1)))]
1013   "rs6000_gen_cell_microcode"
1014   "@
1015    extsh. %0,%1
1016    #"
1017   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1018   [(set (match_dup 0)
1019         (sign_extend:EXTHI (match_dup 1)))
1020    (set (match_dup 2)
1021         (compare:CC (match_dup 0)
1022                     (const_int 0)))]
1023   ""
1024   [(set_attr "type" "exts")
1025    (set_attr "dot" "yes")
1026    (set_attr "length" "4,8")])
1029 (define_insn "extendsi<mode>2"
1030   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1031         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1032   ""
1033   "@
1034    lwa%U1%X1 %0,%1
1035    extsw %0,%1
1036    lfiwax %0,%y1
1037    lxsiwax %x0,%y1
1038    mtvsrwa %x0,%1
1039    vextsw2d %0,%1"
1040   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1041    (set_attr "sign_extend" "yes")])
1043 (define_insn_and_split "*extendsi<mode>2_dot"
1044   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1045         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1046                     (const_int 0)))
1047    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1048   "rs6000_gen_cell_microcode"
1049   "@
1050    extsw. %0,%1
1051    #"
1052   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1053   [(set (match_dup 0)
1054         (sign_extend:EXTSI (match_dup 1)))
1055    (set (match_dup 2)
1056         (compare:CC (match_dup 0)
1057                     (const_int 0)))]
1058   ""
1059   [(set_attr "type" "exts")
1060    (set_attr "dot" "yes")
1061    (set_attr "length" "4,8")])
1063 (define_insn_and_split "*extendsi<mode>2_dot2"
1064   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1065         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1066                     (const_int 0)))
1067    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1068         (sign_extend:EXTSI (match_dup 1)))]
1069   "rs6000_gen_cell_microcode"
1070   "@
1071    extsw. %0,%1
1072    #"
1073   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1074   [(set (match_dup 0)
1075         (sign_extend:EXTSI (match_dup 1)))
1076    (set (match_dup 2)
1077         (compare:CC (match_dup 0)
1078                     (const_int 0)))]
1079   ""
1080   [(set_attr "type" "exts")
1081    (set_attr "dot" "yes")
1082    (set_attr "length" "4,8")])
1084 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1086 (define_insn "*macchwc"
1087   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1088         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1089                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1090                                        (const_int 16))
1091                                       (sign_extend:SI
1092                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1093                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1094                     (const_int 0)))
1095    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1096         (plus:SI (mult:SI (ashiftrt:SI
1097                            (match_dup 2)
1098                            (const_int 16))
1099                           (sign_extend:SI
1100                            (match_dup 1)))
1101                  (match_dup 4)))]
1102   "TARGET_MULHW"
1103   "macchw. %0,%1,%2"
1104   [(set_attr "type" "halfmul")])
1106 (define_insn "*macchw"
1107   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1108         (plus:SI (mult:SI (ashiftrt:SI
1109                            (match_operand:SI 2 "gpc_reg_operand" "r")
1110                            (const_int 16))
1111                           (sign_extend:SI
1112                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1113                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1114   "TARGET_MULHW"
1115   "macchw %0,%1,%2"
1116   [(set_attr "type" "halfmul")])
1118 (define_insn "*macchwuc"
1119   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1120         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1121                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1122                                        (const_int 16))
1123                                       (zero_extend:SI
1124                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1125                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1126                     (const_int 0)))
1127    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1128         (plus:SI (mult:SI (lshiftrt:SI
1129                            (match_dup 2)
1130                            (const_int 16))
1131                           (zero_extend:SI
1132                            (match_dup 1)))
1133                  (match_dup 4)))]
1134   "TARGET_MULHW"
1135   "macchwu. %0,%1,%2"
1136   [(set_attr "type" "halfmul")])
1138 (define_insn "*macchwu"
1139   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1140         (plus:SI (mult:SI (lshiftrt:SI
1141                            (match_operand:SI 2 "gpc_reg_operand" "r")
1142                            (const_int 16))
1143                           (zero_extend:SI
1144                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1145                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1146   "TARGET_MULHW"
1147   "macchwu %0,%1,%2"
1148   [(set_attr "type" "halfmul")])
1150 (define_insn "*machhwc"
1151   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1152         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1153                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1154                                        (const_int 16))
1155                                       (ashiftrt:SI
1156                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1157                                        (const_int 16)))
1158                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1159                     (const_int 0)))
1160    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1161         (plus:SI (mult:SI (ashiftrt:SI
1162                            (match_dup 1)
1163                            (const_int 16))
1164                           (ashiftrt:SI
1165                            (match_dup 2)
1166                            (const_int 16)))
1167                  (match_dup 4)))]
1168   "TARGET_MULHW"
1169   "machhw. %0,%1,%2"
1170   [(set_attr "type" "halfmul")])
1172 (define_insn "*machhw"
1173   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1174         (plus:SI (mult:SI (ashiftrt:SI
1175                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1176                            (const_int 16))
1177                           (ashiftrt:SI
1178                            (match_operand:SI 2 "gpc_reg_operand" "r")
1179                            (const_int 16)))
1180                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1181   "TARGET_MULHW"
1182   "machhw %0,%1,%2"
1183   [(set_attr "type" "halfmul")])
1185 (define_insn "*machhwuc"
1186   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1187         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1188                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1189                                        (const_int 16))
1190                                       (lshiftrt:SI
1191                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1192                                        (const_int 16)))
1193                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1194                     (const_int 0)))
1195    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1196         (plus:SI (mult:SI (lshiftrt:SI
1197                            (match_dup 1)
1198                            (const_int 16))
1199                           (lshiftrt:SI
1200                            (match_dup 2)
1201                            (const_int 16)))
1202                  (match_dup 4)))]
1203   "TARGET_MULHW"
1204   "machhwu. %0,%1,%2"
1205   [(set_attr "type" "halfmul")])
1207 (define_insn "*machhwu"
1208   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1209         (plus:SI (mult:SI (lshiftrt:SI
1210                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1211                            (const_int 16))
1212                           (lshiftrt:SI
1213                            (match_operand:SI 2 "gpc_reg_operand" "r")
1214                            (const_int 16)))
1215                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1216   "TARGET_MULHW"
1217   "machhwu %0,%1,%2"
1218   [(set_attr "type" "halfmul")])
1220 (define_insn "*maclhwc"
1221   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1222         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1223                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1224                                       (sign_extend:SI
1225                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1226                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1227                     (const_int 0)))
1228    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1229         (plus:SI (mult:SI (sign_extend:SI
1230                            (match_dup 1))
1231                           (sign_extend:SI
1232                            (match_dup 2)))
1233                  (match_dup 4)))]
1234   "TARGET_MULHW"
1235   "maclhw. %0,%1,%2"
1236   [(set_attr "type" "halfmul")])
1238 (define_insn "*maclhw"
1239   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1240         (plus:SI (mult:SI (sign_extend:SI
1241                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1242                           (sign_extend:SI
1243                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1244                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1245   "TARGET_MULHW"
1246   "maclhw %0,%1,%2"
1247   [(set_attr "type" "halfmul")])
1249 (define_insn "*maclhwuc"
1250   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1251         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1252                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1253                                       (zero_extend:SI
1254                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1255                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1256                     (const_int 0)))
1257    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1258         (plus:SI (mult:SI (zero_extend:SI
1259                            (match_dup 1))
1260                           (zero_extend:SI
1261                            (match_dup 2)))
1262                  (match_dup 4)))]
1263   "TARGET_MULHW"
1264   "maclhwu. %0,%1,%2"
1265   [(set_attr "type" "halfmul")])
1267 (define_insn "*maclhwu"
1268   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1269         (plus:SI (mult:SI (zero_extend:SI
1270                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1271                           (zero_extend:SI
1272                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1273                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1274   "TARGET_MULHW"
1275   "maclhwu %0,%1,%2"
1276   [(set_attr "type" "halfmul")])
1278 (define_insn "*nmacchwc"
1279   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1280         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1281                               (mult:SI (ashiftrt:SI
1282                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1283                                         (const_int 16))
1284                                        (sign_extend:SI
1285                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1286                     (const_int 0)))
1287    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1288         (minus:SI (match_dup 4)
1289                   (mult:SI (ashiftrt:SI
1290                             (match_dup 2)
1291                             (const_int 16))
1292                            (sign_extend:SI
1293                             (match_dup 1)))))]
1294   "TARGET_MULHW"
1295   "nmacchw. %0,%1,%2"
1296   [(set_attr "type" "halfmul")])
1298 (define_insn "*nmacchw"
1299   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1301                   (mult:SI (ashiftrt:SI
1302                             (match_operand:SI 2 "gpc_reg_operand" "r")
1303                             (const_int 16))
1304                            (sign_extend:SI
1305                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1306   "TARGET_MULHW"
1307   "nmacchw %0,%1,%2"
1308   [(set_attr "type" "halfmul")])
1310 (define_insn "*nmachhwc"
1311   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1313                               (mult:SI (ashiftrt:SI
1314                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1315                                         (const_int 16))
1316                                        (ashiftrt:SI
1317                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1318                                         (const_int 16))))
1319                     (const_int 0)))
1320    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1321         (minus:SI (match_dup 4)
1322                   (mult:SI (ashiftrt:SI
1323                             (match_dup 1)
1324                             (const_int 16))
1325                            (ashiftrt:SI
1326                             (match_dup 2)
1327                             (const_int 16)))))]
1328   "TARGET_MULHW"
1329   "nmachhw. %0,%1,%2"
1330   [(set_attr "type" "halfmul")])
1332 (define_insn "*nmachhw"
1333   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1334         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1335                   (mult:SI (ashiftrt:SI
1336                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1337                             (const_int 16))
1338                            (ashiftrt:SI
1339                             (match_operand:SI 2 "gpc_reg_operand" "r")
1340                             (const_int 16)))))]
1341   "TARGET_MULHW"
1342   "nmachhw %0,%1,%2"
1343   [(set_attr "type" "halfmul")])
1345 (define_insn "*nmaclhwc"
1346   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1347         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1348                               (mult:SI (sign_extend:SI
1349                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1350                                        (sign_extend:SI
1351                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1352                     (const_int 0)))
1353    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1354         (minus:SI (match_dup 4)
1355                   (mult:SI (sign_extend:SI
1356                             (match_dup 1))
1357                            (sign_extend:SI
1358                             (match_dup 2)))))]
1359   "TARGET_MULHW"
1360   "nmaclhw. %0,%1,%2"
1361   [(set_attr "type" "halfmul")])
1363 (define_insn "*nmaclhw"
1364   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1365         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1366                   (mult:SI (sign_extend:SI
1367                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1368                            (sign_extend:SI
1369                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1370   "TARGET_MULHW"
1371   "nmaclhw %0,%1,%2"
1372   [(set_attr "type" "halfmul")])
1374 (define_insn "*mulchwc"
1375   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1376         (compare:CC (mult:SI (ashiftrt:SI
1377                               (match_operand:SI 2 "gpc_reg_operand" "r")
1378                               (const_int 16))
1379                              (sign_extend:SI
1380                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1381                     (const_int 0)))
1382    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1383         (mult:SI (ashiftrt:SI
1384                   (match_dup 2)
1385                   (const_int 16))
1386                  (sign_extend:SI
1387                   (match_dup 1))))]
1388   "TARGET_MULHW"
1389   "mulchw. %0,%1,%2"
1390   [(set_attr "type" "halfmul")])
1392 (define_insn "*mulchw"
1393   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1394         (mult:SI (ashiftrt:SI
1395                   (match_operand:SI 2 "gpc_reg_operand" "r")
1396                   (const_int 16))
1397                  (sign_extend:SI
1398                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1399   "TARGET_MULHW"
1400   "mulchw %0,%1,%2"
1401   [(set_attr "type" "halfmul")])
1403 (define_insn "*mulchwuc"
1404   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1405         (compare:CC (mult:SI (lshiftrt:SI
1406                               (match_operand:SI 2 "gpc_reg_operand" "r")
1407                               (const_int 16))
1408                              (zero_extend:SI
1409                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1410                     (const_int 0)))
1411    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1412         (mult:SI (lshiftrt:SI
1413                   (match_dup 2)
1414                   (const_int 16))
1415                  (zero_extend:SI
1416                   (match_dup 1))))]
1417   "TARGET_MULHW"
1418   "mulchwu. %0,%1,%2"
1419   [(set_attr "type" "halfmul")])
1421 (define_insn "*mulchwu"
1422   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1423         (mult:SI (lshiftrt:SI
1424                   (match_operand:SI 2 "gpc_reg_operand" "r")
1425                   (const_int 16))
1426                  (zero_extend:SI
1427                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1428   "TARGET_MULHW"
1429   "mulchwu %0,%1,%2"
1430   [(set_attr "type" "halfmul")])
1432 (define_insn "*mulhhwc"
1433   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1434         (compare:CC (mult:SI (ashiftrt:SI
1435                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1436                               (const_int 16))
1437                              (ashiftrt:SI
1438                               (match_operand:SI 2 "gpc_reg_operand" "r")
1439                               (const_int 16)))
1440                     (const_int 0)))
1441    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1442         (mult:SI (ashiftrt:SI
1443                   (match_dup 1)
1444                   (const_int 16))
1445                  (ashiftrt:SI
1446                   (match_dup 2)
1447                   (const_int 16))))]
1448   "TARGET_MULHW"
1449   "mulhhw. %0,%1,%2"
1450   [(set_attr "type" "halfmul")])
1452 (define_insn "*mulhhw"
1453   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454         (mult:SI (ashiftrt:SI
1455                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1456                   (const_int 16))
1457                  (ashiftrt:SI
1458                   (match_operand:SI 2 "gpc_reg_operand" "r")
1459                   (const_int 16))))]
1460   "TARGET_MULHW"
1461   "mulhhw %0,%1,%2"
1462   [(set_attr "type" "halfmul")])
1464 (define_insn "*mulhhwuc"
1465   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1466         (compare:CC (mult:SI (lshiftrt:SI
1467                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1468                               (const_int 16))
1469                              (lshiftrt:SI
1470                               (match_operand:SI 2 "gpc_reg_operand" "r")
1471                               (const_int 16)))
1472                     (const_int 0)))
1473    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1474         (mult:SI (lshiftrt:SI
1475                   (match_dup 1)
1476                   (const_int 16))
1477                  (lshiftrt:SI
1478                   (match_dup 2)
1479                   (const_int 16))))]
1480   "TARGET_MULHW"
1481   "mulhhwu. %0,%1,%2"
1482   [(set_attr "type" "halfmul")])
1484 (define_insn "*mulhhwu"
1485   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1486         (mult:SI (lshiftrt:SI
1487                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1488                   (const_int 16))
1489                  (lshiftrt:SI
1490                   (match_operand:SI 2 "gpc_reg_operand" "r")
1491                   (const_int 16))))]
1492   "TARGET_MULHW"
1493   "mulhhwu %0,%1,%2"
1494   [(set_attr "type" "halfmul")])
1496 (define_insn "*mullhwc"
1497   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1498         (compare:CC (mult:SI (sign_extend:SI
1499                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1500                              (sign_extend:SI
1501                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1502                     (const_int 0)))
1503    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1504         (mult:SI (sign_extend:SI
1505                   (match_dup 1))
1506                  (sign_extend:SI
1507                   (match_dup 2))))]
1508   "TARGET_MULHW"
1509   "mullhw. %0,%1,%2"
1510   [(set_attr "type" "halfmul")])
1512 (define_insn "*mullhw"
1513   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1514         (mult:SI (sign_extend:SI
1515                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1516                  (sign_extend:SI
1517                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1518   "TARGET_MULHW"
1519   "mullhw %0,%1,%2"
1520   [(set_attr "type" "halfmul")])
1522 (define_insn "*mullhwuc"
1523   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1524         (compare:CC (mult:SI (zero_extend:SI
1525                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1526                              (zero_extend:SI
1527                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1528                     (const_int 0)))
1529    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1530         (mult:SI (zero_extend:SI
1531                   (match_dup 1))
1532                  (zero_extend:SI
1533                   (match_dup 2))))]
1534   "TARGET_MULHW"
1535   "mullhwu. %0,%1,%2"
1536   [(set_attr "type" "halfmul")])
1538 (define_insn "*mullhwu"
1539   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1540         (mult:SI (zero_extend:SI
1541                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1542                  (zero_extend:SI
1543                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1544   "TARGET_MULHW"
1545   "mullhwu %0,%1,%2"
1546   [(set_attr "type" "halfmul")])
1548 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1549 (define_insn "dlmzb"
1550   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1551         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1552                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1553                    UNSPEC_DLMZB_CR))
1554    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555         (unspec:SI [(match_dup 1)
1556                     (match_dup 2)]
1557                    UNSPEC_DLMZB))]
1558   "TARGET_DLMZB"
1559   "dlmzb. %0,%1,%2")
1561 (define_expand "strlensi"
1562   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1563         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1564                     (match_operand:QI 2 "const_int_operand" "")
1565                     (match_operand 3 "const_int_operand" "")]
1566                    UNSPEC_DLMZB_STRLEN))
1567    (clobber (match_scratch:CC 4 "=x"))]
1568   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1570   rtx result = operands[0];
1571   rtx src = operands[1];
1572   rtx search_char = operands[2];
1573   rtx align = operands[3];
1574   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1575   rtx loop_label, end_label, mem, cr0, cond;
1576   if (search_char != const0_rtx
1577       || GET_CODE (align) != CONST_INT
1578       || INTVAL (align) < 8)
1579         FAIL;
1580   word1 = gen_reg_rtx (SImode);
1581   word2 = gen_reg_rtx (SImode);
1582   scratch_dlmzb = gen_reg_rtx (SImode);
1583   scratch_string = gen_reg_rtx (Pmode);
1584   loop_label = gen_label_rtx ();
1585   end_label = gen_label_rtx ();
1586   addr = force_reg (Pmode, XEXP (src, 0));
1587   emit_move_insn (scratch_string, addr);
1588   emit_label (loop_label);
1589   mem = change_address (src, SImode, scratch_string);
1590   emit_move_insn (word1, mem);
1591   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1592   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1593   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1594   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1595   emit_jump_insn (gen_rtx_SET (pc_rtx,
1596                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1597                                                      cond,
1598                                                      gen_rtx_LABEL_REF
1599                                                        (VOIDmode,
1600                                                         end_label),
1601                                                      pc_rtx)));
1602   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1603   emit_jump_insn (gen_rtx_SET (pc_rtx,
1604                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1605   emit_barrier ();
1606   emit_label (end_label);
1607   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1608   emit_insn (gen_subsi3 (result, scratch_string, addr));
1609   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1610   DONE;
1613 ;; Fixed-point arithmetic insns.
1615 (define_expand "add<mode>3"
1616   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1617         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1618                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1619   ""
1621   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1622     {
1623       rtx lo0 = gen_lowpart (SImode, operands[0]);
1624       rtx lo1 = gen_lowpart (SImode, operands[1]);
1625       rtx lo2 = gen_lowpart (SImode, operands[2]);
1626       rtx hi0 = gen_highpart (SImode, operands[0]);
1627       rtx hi1 = gen_highpart (SImode, operands[1]);
1628       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1630       if (!reg_or_short_operand (lo2, SImode))
1631         lo2 = force_reg (SImode, lo2);
1632       if (!adde_operand (hi2, SImode))
1633         hi2 = force_reg (SImode, hi2);
1635       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1636       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1637       DONE;
1638     }
1640   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1641     {
1642       rtx tmp = ((!can_create_pseudo_p ()
1643                   || rtx_equal_p (operands[0], operands[1]))
1644                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1646       HOST_WIDE_INT val = INTVAL (operands[2]);
1647       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1648       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1650       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1651         FAIL;
1653       /* The ordering here is important for the prolog expander.
1654          When space is allocated from the stack, adding 'low' first may
1655          produce a temporary deallocation (which would be bad).  */
1656       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1657       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1658       DONE;
1659     }
1662 (define_insn "*add<mode>3"
1663   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1664         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1665                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1666   ""
1667   "@
1668    add %0,%1,%2
1669    addi %0,%1,%2
1670    addis %0,%1,%v2"
1671   [(set_attr "type" "add")])
1673 (define_insn "addsi3_high"
1674   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1675         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1676                  (high:SI (match_operand 2 "" ""))))]
1677   "TARGET_MACHO && !TARGET_64BIT"
1678   "addis %0,%1,ha16(%2)"
1679   [(set_attr "type" "add")])
1681 (define_insn_and_split "*add<mode>3_dot"
1682   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1683         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1684                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1685                     (const_int 0)))
1686    (clobber (match_scratch:GPR 0 "=r,r"))]
1687   "<MODE>mode == Pmode"
1688   "@
1689    add. %0,%1,%2
1690    #"
1691   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1692   [(set (match_dup 0)
1693         (plus:GPR (match_dup 1)
1694                  (match_dup 2)))
1695    (set (match_dup 3)
1696         (compare:CC (match_dup 0)
1697                     (const_int 0)))]
1698   ""
1699   [(set_attr "type" "add")
1700    (set_attr "dot" "yes")
1701    (set_attr "length" "4,8")])
1703 (define_insn_and_split "*add<mode>3_dot2"
1704   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1705         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1706                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1707                     (const_int 0)))
1708    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1709         (plus:GPR (match_dup 1)
1710                   (match_dup 2)))]
1711   "<MODE>mode == Pmode"
1712   "@
1713    add. %0,%1,%2
1714    #"
1715   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1716   [(set (match_dup 0)
1717         (plus:GPR (match_dup 1)
1718                   (match_dup 2)))
1719    (set (match_dup 3)
1720         (compare:CC (match_dup 0)
1721                     (const_int 0)))]
1722   ""
1723   [(set_attr "type" "add")
1724    (set_attr "dot" "yes")
1725    (set_attr "length" "4,8")])
1727 (define_insn_and_split "*add<mode>3_imm_dot"
1728   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1729         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1730                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1731                     (const_int 0)))
1732    (clobber (match_scratch:GPR 0 "=r,r"))
1733    (clobber (reg:GPR CA_REGNO))]
1734   "<MODE>mode == Pmode"
1735   "@
1736    addic. %0,%1,%2
1737    #"
1738   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1739   [(set (match_dup 0)
1740         (plus:GPR (match_dup 1)
1741                   (match_dup 2)))
1742    (set (match_dup 3)
1743         (compare:CC (match_dup 0)
1744                     (const_int 0)))]
1745   ""
1746   [(set_attr "type" "add")
1747    (set_attr "dot" "yes")
1748    (set_attr "length" "4,8")])
1750 (define_insn_and_split "*add<mode>3_imm_dot2"
1751   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1752         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1753                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1754                     (const_int 0)))
1755    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1756         (plus:GPR (match_dup 1)
1757                   (match_dup 2)))
1758    (clobber (reg:GPR CA_REGNO))]
1759   "<MODE>mode == Pmode"
1760   "@
1761    addic. %0,%1,%2
1762    #"
1763   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1764   [(set (match_dup 0)
1765         (plus:GPR (match_dup 1)
1766                   (match_dup 2)))
1767    (set (match_dup 3)
1768         (compare:CC (match_dup 0)
1769                     (const_int 0)))]
1770   ""
1771   [(set_attr "type" "add")
1772    (set_attr "dot" "yes")
1773    (set_attr "length" "4,8")])
1775 ;; Split an add that we can't do in one insn into two insns, each of which
1776 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1777 ;; add should be last in case the result gets used in an address.
1779 (define_split
1780   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1781         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1782                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1783   ""
1784   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1785    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1787   HOST_WIDE_INT val = INTVAL (operands[2]);
1788   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1789   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1791   operands[4] = GEN_INT (low);
1792   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1793     operands[3] = GEN_INT (rest);
1794   else if (can_create_pseudo_p ())
1795     {
1796       operands[3] = gen_reg_rtx (DImode);
1797       emit_move_insn (operands[3], operands[2]);
1798       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1799       DONE;
1800     }
1801   else
1802     FAIL;
1806 (define_insn "add<mode>3_carry"
1807   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1808         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1809                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1810    (set (reg:P CA_REGNO)
1811         (ltu:P (plus:P (match_dup 1)
1812                        (match_dup 2))
1813                (match_dup 1)))]
1814   ""
1815   "add%I2c %0,%1,%2"
1816   [(set_attr "type" "add")])
1818 (define_insn "*add<mode>3_imm_carry_pos"
1819   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1820         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1821                 (match_operand:P 2 "short_cint_operand" "n")))
1822    (set (reg:P CA_REGNO)
1823         (geu:P (match_dup 1)
1824                (match_operand:P 3 "const_int_operand" "n")))]
1825   "INTVAL (operands[2]) > 0
1826    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1827   "addic %0,%1,%2"
1828   [(set_attr "type" "add")])
1830 (define_insn "*add<mode>3_imm_carry_0"
1831   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1832         (match_operand:P 1 "gpc_reg_operand" "r"))
1833    (set (reg:P CA_REGNO)
1834         (const_int 0))]
1835   ""
1836   "addic %0,%1,0"
1837   [(set_attr "type" "add")])
1839 (define_insn "*add<mode>3_imm_carry_m1"
1840   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1841         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1842                 (const_int -1)))
1843    (set (reg:P CA_REGNO)
1844         (ne:P (match_dup 1)
1845               (const_int 0)))]
1846   ""
1847   "addic %0,%1,-1"
1848   [(set_attr "type" "add")])
1850 (define_insn "*add<mode>3_imm_carry_neg"
1851   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1852         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1853                 (match_operand:P 2 "short_cint_operand" "n")))
1854    (set (reg:P CA_REGNO)
1855         (gtu:P (match_dup 1)
1856                (match_operand:P 3 "const_int_operand" "n")))]
1857   "INTVAL (operands[2]) < 0
1858    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1859   "addic %0,%1,%2"
1860   [(set_attr "type" "add")])
1863 (define_expand "add<mode>3_carry_in"
1864   [(parallel [
1865      (set (match_operand:GPR 0 "gpc_reg_operand")
1866           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1867                               (match_operand:GPR 2 "adde_operand"))
1868                     (reg:GPR CA_REGNO)))
1869      (clobber (reg:GPR CA_REGNO))])]
1870   ""
1872   if (operands[2] == const0_rtx)
1873     {
1874       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1875       DONE;
1876     }
1877   if (operands[2] == constm1_rtx)
1878     {
1879       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1880       DONE;
1881     }
1884 (define_insn "*add<mode>3_carry_in_internal"
1885   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1886         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1887                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1888                   (reg:GPR CA_REGNO)))
1889    (clobber (reg:GPR CA_REGNO))]
1890   ""
1891   "adde %0,%1,%2"
1892   [(set_attr "type" "add")])
1894 (define_insn "add<mode>3_carry_in_0"
1895   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1896         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1897                   (reg:GPR CA_REGNO)))
1898    (clobber (reg:GPR CA_REGNO))]
1899   ""
1900   "addze %0,%1"
1901   [(set_attr "type" "add")])
1903 (define_insn "add<mode>3_carry_in_m1"
1904   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1906                             (reg:GPR CA_REGNO))
1907                   (const_int -1)))
1908    (clobber (reg:GPR CA_REGNO))]
1909   ""
1910   "addme %0,%1"
1911   [(set_attr "type" "add")])
1914 (define_expand "one_cmpl<mode>2"
1915   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1916         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1917   ""
1919   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1920     {
1921       rs6000_split_logical (operands, NOT, false, false, false);
1922       DONE;
1923     }
1926 (define_insn "*one_cmpl<mode>2"
1927   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1928         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1929   ""
1930   "not %0,%1")
1932 (define_insn_and_split "*one_cmpl<mode>2_dot"
1933   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1934         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1935                     (const_int 0)))
1936    (clobber (match_scratch:GPR 0 "=r,r"))]
1937   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1938   "@
1939    not. %0,%1
1940    #"
1941   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1942   [(set (match_dup 0)
1943         (not:GPR (match_dup 1)))
1944    (set (match_dup 2)
1945         (compare:CC (match_dup 0)
1946                     (const_int 0)))]
1947   ""
1948   [(set_attr "type" "logical")
1949    (set_attr "dot" "yes")
1950    (set_attr "length" "4,8")])
1952 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1953   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1954         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1955                     (const_int 0)))
1956    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1957         (not:GPR (match_dup 1)))]
1958   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1959   "@
1960    not. %0,%1
1961    #"
1962   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1963   [(set (match_dup 0)
1964         (not:GPR (match_dup 1)))
1965    (set (match_dup 2)
1966         (compare:CC (match_dup 0)
1967                     (const_int 0)))]
1968   ""
1969   [(set_attr "type" "logical")
1970    (set_attr "dot" "yes")
1971    (set_attr "length" "4,8")])
1974 (define_expand "sub<mode>3"
1975   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1976         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1977                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1978   ""
1980   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1981     {
1982       rtx lo0 = gen_lowpart (SImode, operands[0]);
1983       rtx lo1 = gen_lowpart (SImode, operands[1]);
1984       rtx lo2 = gen_lowpart (SImode, operands[2]);
1985       rtx hi0 = gen_highpart (SImode, operands[0]);
1986       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1987       rtx hi2 = gen_highpart (SImode, operands[2]);
1989       if (!reg_or_short_operand (lo1, SImode))
1990         lo1 = force_reg (SImode, lo1);
1991       if (!adde_operand (hi1, SImode))
1992         hi1 = force_reg (SImode, hi1);
1994       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1995       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1996       DONE;
1997     }
1999   if (short_cint_operand (operands[1], <MODE>mode))
2000     {
2001       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2002       DONE;
2003     }
2006 (define_insn "*subf<mode>3"
2007   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2008         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2009                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2010   ""
2011   "subf %0,%1,%2"
2012   [(set_attr "type" "add")])
2014 (define_insn_and_split "*subf<mode>3_dot"
2015   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2016         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2017                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2018                     (const_int 0)))
2019    (clobber (match_scratch:GPR 0 "=r,r"))]
2020   "<MODE>mode == Pmode"
2021   "@
2022    subf. %0,%1,%2
2023    #"
2024   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2025   [(set (match_dup 0)
2026         (minus:GPR (match_dup 2)
2027                    (match_dup 1)))
2028    (set (match_dup 3)
2029         (compare:CC (match_dup 0)
2030                     (const_int 0)))]
2031   ""
2032   [(set_attr "type" "add")
2033    (set_attr "dot" "yes")
2034    (set_attr "length" "4,8")])
2036 (define_insn_and_split "*subf<mode>3_dot2"
2037   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2038         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2039                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2040                     (const_int 0)))
2041    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2042         (minus:GPR (match_dup 2)
2043                    (match_dup 1)))]
2044   "<MODE>mode == Pmode"
2045   "@
2046    subf. %0,%1,%2
2047    #"
2048   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2049   [(set (match_dup 0)
2050         (minus:GPR (match_dup 2)
2051                    (match_dup 1)))
2052    (set (match_dup 3)
2053         (compare:CC (match_dup 0)
2054                     (const_int 0)))]
2055   ""
2056   [(set_attr "type" "add")
2057    (set_attr "dot" "yes")
2058    (set_attr "length" "4,8")])
2060 (define_insn "subf<mode>3_imm"
2061   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2062         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2063                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2064    (clobber (reg:GPR CA_REGNO))]
2065   ""
2066   "subfic %0,%1,%2"
2067   [(set_attr "type" "add")])
2069 (define_insn_and_split "subf<mode>3_carry_dot2"
2070   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2071         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2072                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2073                     (const_int 0)))
2074    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2075         (minus:P (match_dup 2)
2076                    (match_dup 1)))
2077    (set (reg:P CA_REGNO)
2078         (leu:P (match_dup 1)
2079                (match_dup 2)))]
2080   "<MODE>mode == Pmode"
2081   "@
2082    subfc. %0,%1,%2
2083    #"
2084   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2085   [(parallel [(set (match_dup 0)
2086                    (minus:P (match_dup 2)
2087                             (match_dup 1)))
2088               (set (reg:P CA_REGNO)
2089                    (leu:P (match_dup 1)
2090                           (match_dup 2)))])
2091    (set (match_dup 3)
2092         (compare:CC (match_dup 0)
2093                     (const_int 0)))]
2094   ""
2095   [(set_attr "type" "add")
2096    (set_attr "dot" "yes")
2097    (set_attr "length" "4,8")])
2099 (define_insn "subf<mode>3_carry"
2100   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2101         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2102                  (match_operand:P 1 "gpc_reg_operand" "r")))
2103    (set (reg:P CA_REGNO)
2104         (leu:P (match_dup 1)
2105                (match_dup 2)))]
2106   ""
2107   "subf%I2c %0,%1,%2"
2108   [(set_attr "type" "add")])
2110 (define_insn "*subf<mode>3_imm_carry_0"
2111   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2112         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2113    (set (reg:P CA_REGNO)
2114         (eq:P (match_dup 1)
2115               (const_int 0)))]
2116   ""
2117   "subfic %0,%1,0"
2118   [(set_attr "type" "add")])
2120 (define_insn "*subf<mode>3_imm_carry_m1"
2121   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2122         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2123    (set (reg:P CA_REGNO)
2124         (const_int 1))]
2125   ""
2126   "subfic %0,%1,-1"
2127   [(set_attr "type" "add")])
2130 (define_expand "subf<mode>3_carry_in"
2131   [(parallel [
2132      (set (match_operand:GPR 0 "gpc_reg_operand")
2133           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2134                               (reg:GPR CA_REGNO))
2135                     (match_operand:GPR 2 "adde_operand")))
2136      (clobber (reg:GPR CA_REGNO))])]
2137   ""
2139   if (operands[2] == const0_rtx)
2140     {
2141       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2142       DONE;
2143     }
2144   if (operands[2] == constm1_rtx)
2145     {
2146       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2147       DONE;
2148     }
2151 (define_insn "*subf<mode>3_carry_in_internal"
2152   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2153         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2154                             (reg:GPR CA_REGNO))
2155                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2156    (clobber (reg:GPR CA_REGNO))]
2157   ""
2158   "subfe %0,%1,%2"
2159   [(set_attr "type" "add")])
2161 (define_insn "subf<mode>3_carry_in_0"
2162   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2163         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2164                   (reg:GPR CA_REGNO)))
2165    (clobber (reg:GPR CA_REGNO))]
2166   ""
2167   "subfze %0,%1"
2168   [(set_attr "type" "add")])
2170 (define_insn "subf<mode>3_carry_in_m1"
2171   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2172         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2173                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2174                   (const_int -2)))
2175    (clobber (reg:GPR CA_REGNO))]
2176   ""
2177   "subfme %0,%1"
2178   [(set_attr "type" "add")])
2180 (define_insn "subf<mode>3_carry_in_xx"
2181   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2182         (plus:GPR (reg:GPR CA_REGNO)
2183                   (const_int -1)))
2184    (clobber (reg:GPR CA_REGNO))]
2185   ""
2186   "subfe %0,%0,%0"
2187   [(set_attr "type" "add")])
2190 (define_insn "neg<mode>2"
2191   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2192         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2193   ""
2194   "neg %0,%1"
2195   [(set_attr "type" "add")])
2197 (define_insn_and_split "*neg<mode>2_dot"
2198   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2199         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2200                     (const_int 0)))
2201    (clobber (match_scratch:GPR 0 "=r,r"))]
2202   "<MODE>mode == Pmode"
2203   "@
2204    neg. %0,%1
2205    #"
2206   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2207   [(set (match_dup 0)
2208         (neg:GPR (match_dup 1)))
2209    (set (match_dup 2)
2210         (compare:CC (match_dup 0)
2211                     (const_int 0)))]
2212   ""
2213   [(set_attr "type" "add")
2214    (set_attr "dot" "yes")
2215    (set_attr "length" "4,8")])
2217 (define_insn_and_split "*neg<mode>2_dot2"
2218   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2219         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2220                     (const_int 0)))
2221    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2222         (neg:GPR (match_dup 1)))]
2223   "<MODE>mode == Pmode"
2224   "@
2225    neg. %0,%1
2226    #"
2227   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2228   [(set (match_dup 0)
2229         (neg:GPR (match_dup 1)))
2230    (set (match_dup 2)
2231         (compare:CC (match_dup 0)
2232                     (const_int 0)))]
2233   ""
2234   [(set_attr "type" "add")
2235    (set_attr "dot" "yes")
2236    (set_attr "length" "4,8")])
2239 (define_insn "clz<mode>2"
2240   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2241         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2242   ""
2243   "cntlz<wd> %0,%1"
2244   [(set_attr "type" "cntlz")])
2246 (define_expand "ctz<mode>2"
2247    [(set (match_operand:GPR 0 "gpc_reg_operand")
2248          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2249   ""
2251   if (TARGET_CTZ)
2252     {
2253       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2254       DONE;
2255     }
2257   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2258   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2259   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2261   if (TARGET_POPCNTD)
2262     {
2263       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2264       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2265       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2266       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2267     }
2268   else
2269     {
2270       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2271       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2272       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2273       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2274     }
2276   DONE;
2279 (define_insn "ctz<mode>2_hw"
2280   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2281         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2282   "TARGET_CTZ"
2283   "cnttz<wd> %0,%1"
2284   [(set_attr "type" "cntlz")])
2286 (define_expand "ffs<mode>2"
2287   [(set (match_operand:GPR 0 "gpc_reg_operand")
2288         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2289   ""
2291   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2292   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2293   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2294   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2295   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2296   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2297   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2298   DONE;
2302 (define_expand "popcount<mode>2"
2303   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2304         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2305   "TARGET_POPCNTB || TARGET_POPCNTD"
2307   rs6000_emit_popcount (operands[0], operands[1]);
2308   DONE;
2311 (define_insn "popcntb<mode>2"
2312   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2313         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2314                     UNSPEC_POPCNTB))]
2315   "TARGET_POPCNTB"
2316   "popcntb %0,%1"
2317   [(set_attr "type" "popcnt")])
2319 (define_insn "popcntd<mode>2"
2320   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2321         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2322   "TARGET_POPCNTD"
2323   "popcnt<wd> %0,%1"
2324   [(set_attr "type" "popcnt")])
2327 (define_expand "parity<mode>2"
2328   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2329         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2330   "TARGET_POPCNTB"
2332   rs6000_emit_parity (operands[0], operands[1]);
2333   DONE;
2336 (define_insn "parity<mode>2_cmpb"
2337   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2338         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2339   "TARGET_CMPB && TARGET_POPCNTB"
2340   "prty<wd> %0,%1"
2341   [(set_attr "type" "popcnt")])
2343 (define_insn "cmpb<mode>3"
2344   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2345         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2346                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2347   "TARGET_CMPB"
2348   "cmpb %0,%1,%2"
2349   [(set_attr "type" "cmp")])
2351 ;; Since the hardware zeros the upper part of the register, save generating the
2352 ;; AND immediate if we are converting to unsigned
2353 (define_insn "*bswaphi2_extenddi"
2354   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2355         (zero_extend:DI
2356          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2357   "TARGET_POWERPC64"
2358   "lhbrx %0,%y1"
2359   [(set_attr "length" "4")
2360    (set_attr "type" "load")])
2362 (define_insn "*bswaphi2_extendsi"
2363   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2364         (zero_extend:SI
2365          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2366   ""
2367   "lhbrx %0,%y1"
2368   [(set_attr "length" "4")
2369    (set_attr "type" "load")])
2371 (define_expand "bswaphi2"
2372   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2373                    (bswap:HI
2374                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2375               (clobber (match_scratch:SI 2 ""))])]
2376   ""
2378   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2379     operands[1] = force_reg (HImode, operands[1]);
2382 (define_insn "bswaphi2_internal"
2383   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2384         (bswap:HI
2385          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2386    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2387   ""
2388   "@
2389    lhbrx %0,%y1
2390    sthbrx %1,%y0
2391    #"
2392   [(set_attr "length" "4,4,12")
2393    (set_attr "type" "load,store,*")])
2395 (define_split
2396   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2397         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2398    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2399   "reload_completed"
2400   [(set (match_dup 3)
2401         (and:SI (lshiftrt:SI (match_dup 4)
2402                              (const_int 8))
2403                 (const_int 255)))
2404    (set (match_dup 2)
2405         (and:SI (ashift:SI (match_dup 4)
2406                            (const_int 8))
2407                 (const_int 65280)))             ;; 0xff00
2408    (set (match_dup 3)
2409         (ior:SI (match_dup 3)
2410                 (match_dup 2)))]
2411   "
2413   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2414   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2417 (define_insn "*bswapsi2_extenddi"
2418   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2419         (zero_extend:DI
2420          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2421   "TARGET_POWERPC64"
2422   "lwbrx %0,%y1"
2423   [(set_attr "length" "4")
2424    (set_attr "type" "load")])
2426 (define_expand "bswapsi2"
2427   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2428         (bswap:SI
2429          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2430   ""
2432   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2433     operands[1] = force_reg (SImode, operands[1]);
2436 (define_insn "*bswapsi2_internal"
2437   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2438         (bswap:SI
2439          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2440   ""
2441   "@
2442    lwbrx %0,%y1
2443    stwbrx %1,%y0
2444    #"
2445   [(set_attr "length" "4,4,12")
2446    (set_attr "type" "load,store,*")])
2448 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2449 ;; zero_extract insns do not change for -mlittle.
2450 (define_split
2451   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2452         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2453   "reload_completed"
2454   [(set (match_dup 0)                                   ; DABC
2455         (rotate:SI (match_dup 1)
2456                    (const_int 24)))
2457    (set (match_dup 0)                                   ; DCBC
2458         (ior:SI (and:SI (ashift:SI (match_dup 1)
2459                                    (const_int 8))
2460                         (const_int 16711680))
2461                 (and:SI (match_dup 0)
2462                         (const_int -16711681))))
2463    (set (match_dup 0)                                   ; DCBA
2464         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2465                                      (const_int 24))
2466                         (const_int 255))
2467                 (and:SI (match_dup 0)
2468                         (const_int -256))))
2470   ]
2471   "")
2473 (define_expand "bswapdi2"
2474   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2475                    (bswap:DI
2476                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2477               (clobber (match_scratch:DI 2 ""))
2478               (clobber (match_scratch:DI 3 ""))])]
2479   ""
2481   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2482     operands[1] = force_reg (DImode, operands[1]);
2484   if (!TARGET_POWERPC64)
2485     {
2486       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2487          that uses 64-bit registers needs the same scratch registers as 64-bit
2488          mode.  */
2489       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2490       DONE;
2491     }
2494 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2495 (define_insn "*bswapdi2_ldbrx"
2496   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2497         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2498    (clobber (match_scratch:DI 2 "=X,X,&r"))
2499    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2500   "TARGET_POWERPC64 && TARGET_LDBRX
2501    && (REG_P (operands[0]) || REG_P (operands[1]))"
2502   "@
2503    ldbrx %0,%y1
2504    stdbrx %1,%y0
2505    #"
2506   [(set_attr "length" "4,4,36")
2507    (set_attr "type" "load,store,*")])
2509 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2510 (define_insn "*bswapdi2_64bit"
2511   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2512         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2513    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2514    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2515   "TARGET_POWERPC64 && !TARGET_LDBRX
2516    && (REG_P (operands[0]) || REG_P (operands[1]))
2517    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2518    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2519   "#"
2520   [(set_attr "length" "16,12,36")])
2522 (define_split
2523   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2524         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2525    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2526    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2527   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2528   [(const_int 0)]
2529   "
2531   rtx dest   = operands[0];
2532   rtx src    = operands[1];
2533   rtx op2    = operands[2];
2534   rtx op3    = operands[3];
2535   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2536                                     BYTES_BIG_ENDIAN ? 4 : 0);
2537   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2538                                      BYTES_BIG_ENDIAN ? 4 : 0);
2539   rtx addr1;
2540   rtx addr2;
2541   rtx word1;
2542   rtx word2;
2544   addr1 = XEXP (src, 0);
2545   if (GET_CODE (addr1) == PLUS)
2546     {
2547       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2548       if (TARGET_AVOID_XFORM)
2549         {
2550           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2551           addr2 = op2;
2552         }
2553       else
2554         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2555     }
2556   else if (TARGET_AVOID_XFORM)
2557     {
2558       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2559       addr2 = op2;
2560     }
2561   else
2562     {
2563       emit_move_insn (op2, GEN_INT (4));
2564       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2565     }
2567   word1 = change_address (src, SImode, addr1);
2568   word2 = change_address (src, SImode, addr2);
2570   if (BYTES_BIG_ENDIAN)
2571     {
2572       emit_insn (gen_bswapsi2 (op3_32, word2));
2573       emit_insn (gen_bswapsi2 (dest_32, word1));
2574     }
2575   else
2576     {
2577       emit_insn (gen_bswapsi2 (op3_32, word1));
2578       emit_insn (gen_bswapsi2 (dest_32, word2));
2579     }
2581   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2582   emit_insn (gen_iordi3 (dest, dest, op3));
2583   DONE;
2586 (define_split
2587   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2588         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2589    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2590    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2591   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2592   [(const_int 0)]
2593   "
2595   rtx dest   = operands[0];
2596   rtx src    = operands[1];
2597   rtx op2    = operands[2];
2598   rtx op3    = operands[3];
2599   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2600                                     BYTES_BIG_ENDIAN ? 4 : 0);
2601   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2602                                     BYTES_BIG_ENDIAN ? 4 : 0);
2603   rtx addr1;
2604   rtx addr2;
2605   rtx word1;
2606   rtx word2;
2608   addr1 = XEXP (dest, 0);
2609   if (GET_CODE (addr1) == PLUS)
2610     {
2611       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2612       if (TARGET_AVOID_XFORM)
2613         {
2614           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2615           addr2 = op2;
2616         }
2617       else
2618         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2619     }
2620   else if (TARGET_AVOID_XFORM)
2621     {
2622       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2623       addr2 = op2;
2624     }
2625   else
2626     {
2627       emit_move_insn (op2, GEN_INT (4));
2628       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2629     }
2631   word1 = change_address (dest, SImode, addr1);
2632   word2 = change_address (dest, SImode, addr2);
2634   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2636   if (BYTES_BIG_ENDIAN)
2637     {
2638       emit_insn (gen_bswapsi2 (word1, src_si));
2639       emit_insn (gen_bswapsi2 (word2, op3_si));
2640     }
2641   else
2642     {
2643       emit_insn (gen_bswapsi2 (word2, src_si));
2644       emit_insn (gen_bswapsi2 (word1, op3_si));
2645     }
2646   DONE;
2649 (define_split
2650   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2651         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2652    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2653    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2654   "TARGET_POWERPC64 && reload_completed"
2655   [(const_int 0)]
2656   "
2658   rtx dest    = operands[0];
2659   rtx src     = operands[1];
2660   rtx op2     = operands[2];
2661   rtx op3     = operands[3];
2662   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2663   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2664   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2665   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2666   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2668   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2669   emit_insn (gen_bswapsi2 (dest_si, src_si));
2670   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2671   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2672   emit_insn (gen_iordi3 (dest, dest, op3));
2673   DONE;
2676 (define_insn "bswapdi2_32bit"
2677   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2678         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2679    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2680   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2681   "#"
2682   [(set_attr "length" "16,12,36")])
2684 (define_split
2685   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2686         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2687    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2688   "!TARGET_POWERPC64 && reload_completed"
2689   [(const_int 0)]
2690   "
2692   rtx dest  = operands[0];
2693   rtx src   = operands[1];
2694   rtx op2   = operands[2];
2695   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2696   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2697   rtx addr1;
2698   rtx addr2;
2699   rtx word1;
2700   rtx word2;
2702   addr1 = XEXP (src, 0);
2703   if (GET_CODE (addr1) == PLUS)
2704     {
2705       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2706       if (TARGET_AVOID_XFORM
2707           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2708         {
2709           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2710           addr2 = op2;
2711         }
2712       else
2713         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2714     }
2715   else if (TARGET_AVOID_XFORM
2716            || REGNO (addr1) == REGNO (dest2))
2717     {
2718       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2719       addr2 = op2;
2720     }
2721   else
2722     {
2723       emit_move_insn (op2, GEN_INT (4));
2724       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2725     }
2727   word1 = change_address (src, SImode, addr1);
2728   word2 = change_address (src, SImode, addr2);
2730   emit_insn (gen_bswapsi2 (dest2, word1));
2731   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2732      thus allowing us to omit an early clobber on the output.  */
2733   emit_insn (gen_bswapsi2 (dest1, word2));
2734   DONE;
2737 (define_split
2738   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2739         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2740    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2741   "!TARGET_POWERPC64 && reload_completed"
2742   [(const_int 0)]
2743   "
2745   rtx dest = operands[0];
2746   rtx src  = operands[1];
2747   rtx op2  = operands[2];
2748   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2749   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2750   rtx addr1;
2751   rtx addr2;
2752   rtx word1;
2753   rtx word2;
2755   addr1 = XEXP (dest, 0);
2756   if (GET_CODE (addr1) == PLUS)
2757     {
2758       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2759       if (TARGET_AVOID_XFORM)
2760         {
2761           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2762           addr2 = op2;
2763         }
2764       else
2765         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2766     }
2767   else if (TARGET_AVOID_XFORM)
2768     {
2769       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2770       addr2 = op2;
2771     }
2772   else
2773     {
2774       emit_move_insn (op2, GEN_INT (4));
2775       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2776     }
2778   word1 = change_address (dest, SImode, addr1);
2779   word2 = change_address (dest, SImode, addr2);
2781   emit_insn (gen_bswapsi2 (word2, src1));
2782   emit_insn (gen_bswapsi2 (word1, src2));
2783   DONE;
2786 (define_split
2787   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2788         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2789    (clobber (match_operand:SI 2 "" ""))]
2790   "!TARGET_POWERPC64 && reload_completed"
2791   [(const_int 0)]
2792   "
2794   rtx dest  = operands[0];
2795   rtx src   = operands[1];
2796   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2797   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2798   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2799   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2801   emit_insn (gen_bswapsi2 (dest1, src2));
2802   emit_insn (gen_bswapsi2 (dest2, src1));
2803   DONE;
2807 (define_insn "mul<mode>3"
2808   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2809         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2810                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2811   ""
2812   "@
2813    mull<wd> %0,%1,%2
2814    mulli %0,%1,%2"
2815    [(set_attr "type" "mul")
2816     (set (attr "size")
2817       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2818                 (const_string "8")
2819              (match_operand:GPR 2 "short_cint_operand" "")
2820                 (const_string "16")]
2821         (const_string "<bits>")))])
2823 (define_insn_and_split "*mul<mode>3_dot"
2824   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2825         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2826                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2827                     (const_int 0)))
2828    (clobber (match_scratch:GPR 0 "=r,r"))]
2829   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2830   "@
2831    mull<wd>. %0,%1,%2
2832    #"
2833   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2834   [(set (match_dup 0)
2835         (mult:GPR (match_dup 1)
2836                   (match_dup 2)))
2837    (set (match_dup 3)
2838         (compare:CC (match_dup 0)
2839                     (const_int 0)))]
2840   ""
2841   [(set_attr "type" "mul")
2842    (set_attr "size" "<bits>")
2843    (set_attr "dot" "yes")
2844    (set_attr "length" "4,8")])
2846 (define_insn_and_split "*mul<mode>3_dot2"
2847   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2848         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2849                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2850                     (const_int 0)))
2851    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2852         (mult:GPR (match_dup 1)
2853                   (match_dup 2)))]
2854   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2855   "@
2856    mull<wd>. %0,%1,%2
2857    #"
2858   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2859   [(set (match_dup 0)
2860         (mult:GPR (match_dup 1)
2861                   (match_dup 2)))
2862    (set (match_dup 3)
2863         (compare:CC (match_dup 0)
2864                     (const_int 0)))]
2865   ""
2866   [(set_attr "type" "mul")
2867    (set_attr "size" "<bits>")
2868    (set_attr "dot" "yes")
2869    (set_attr "length" "4,8")])
2872 (define_expand "<su>mul<mode>3_highpart"
2873   [(set (match_operand:GPR 0 "gpc_reg_operand")
2874         (subreg:GPR
2875           (mult:<DMODE> (any_extend:<DMODE>
2876                           (match_operand:GPR 1 "gpc_reg_operand"))
2877                         (any_extend:<DMODE>
2878                           (match_operand:GPR 2 "gpc_reg_operand")))
2879          0))]
2880   ""
2882   if (<MODE>mode == SImode && TARGET_POWERPC64)
2883     {
2884       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2885                                              operands[2]));
2886       DONE;
2887     }
2889   if (!WORDS_BIG_ENDIAN)
2890     {
2891       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2892                                                  operands[2]));
2893       DONE;
2894     }
2897 (define_insn "*<su>mul<mode>3_highpart"
2898   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2899         (subreg:GPR
2900           (mult:<DMODE> (any_extend:<DMODE>
2901                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2902                         (any_extend:<DMODE>
2903                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2904          0))]
2905   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2906   "mulh<wd><u> %0,%1,%2"
2907   [(set_attr "type" "mul")
2908    (set_attr "size" "<bits>")])
2910 (define_insn "<su>mulsi3_highpart_le"
2911   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2912         (subreg:SI
2913           (mult:DI (any_extend:DI
2914                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2915                    (any_extend:DI
2916                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2917          4))]
2918   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2919   "mulhw<u> %0,%1,%2"
2920   [(set_attr "type" "mul")])
2922 (define_insn "<su>muldi3_highpart_le"
2923   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2924         (subreg:DI
2925           (mult:TI (any_extend:TI
2926                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2927                    (any_extend:TI
2928                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2929          8))]
2930   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2931   "mulhd<u> %0,%1,%2"
2932   [(set_attr "type" "mul")
2933    (set_attr "size" "64")])
2935 (define_insn "<su>mulsi3_highpart_64"
2936   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2937         (truncate:SI
2938           (lshiftrt:DI
2939             (mult:DI (any_extend:DI
2940                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2941                      (any_extend:DI
2942                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2943             (const_int 32))))]
2944   "TARGET_POWERPC64"
2945   "mulhw<u> %0,%1,%2"
2946   [(set_attr "type" "mul")])
2948 (define_expand "<u>mul<mode><dmode>3"
2949   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2950         (mult:<DMODE> (any_extend:<DMODE>
2951                         (match_operand:GPR 1 "gpc_reg_operand"))
2952                       (any_extend:<DMODE>
2953                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2954   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2956   rtx l = gen_reg_rtx (<MODE>mode);
2957   rtx h = gen_reg_rtx (<MODE>mode);
2958   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2959   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2960   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2961   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2962   DONE;
2965 (define_insn "*maddld4"
2966   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2967         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2968                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2969                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2970   "TARGET_MADDLD"
2971   "maddld %0,%1,%2,%3"
2972   [(set_attr "type" "mul")])
2974 (define_insn "udiv<mode>3"
2975   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2976         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2977                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2978   ""
2979   "div<wd>u %0,%1,%2"
2980   [(set_attr "type" "div")
2981    (set_attr "size" "<bits>")])
2984 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2985 ;; modulus.  If it isn't a power of two, force operands into register and do
2986 ;; a normal divide.
2987 (define_expand "div<mode>3"
2988   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2989         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2990                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2991   ""
2993   if (CONST_INT_P (operands[2])
2994       && INTVAL (operands[2]) > 0
2995       && exact_log2 (INTVAL (operands[2])) >= 0)
2996     {
2997       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2998       DONE;
2999     }
3001   operands[2] = force_reg (<MODE>mode, operands[2]);
3004 (define_insn "*div<mode>3"
3005   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3006         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3007                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3008   ""
3009   "div<wd> %0,%1,%2"
3010   [(set_attr "type" "div")
3011    (set_attr "size" "<bits>")])
3013 (define_insn "div<mode>3_sra"
3014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3015         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3016                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3017    (clobber (reg:GPR CA_REGNO))]
3018   ""
3019   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3020   [(set_attr "type" "two")
3021    (set_attr "length" "8")])
3023 (define_insn_and_split "*div<mode>3_sra_dot"
3024   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3025         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3026                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3027                     (const_int 0)))
3028    (clobber (match_scratch:GPR 0 "=r,r"))
3029    (clobber (reg:GPR CA_REGNO))]
3030   "<MODE>mode == Pmode"
3031   "@
3032    sra<wd>i %0,%1,%p2\;addze. %0,%0
3033    #"
3034   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3035   [(parallel [(set (match_dup 0)
3036                    (div:GPR (match_dup 1)
3037                             (match_dup 2)))
3038               (clobber (reg:GPR CA_REGNO))])
3039    (set (match_dup 3)
3040         (compare:CC (match_dup 0)
3041                     (const_int 0)))]
3042   ""
3043   [(set_attr "type" "two")
3044    (set_attr "length" "8,12")
3045    (set_attr "cell_micro" "not")])
3047 (define_insn_and_split "*div<mode>3_sra_dot2"
3048   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3049         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3050                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3051                     (const_int 0)))
3052    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3053         (div:GPR (match_dup 1)
3054                  (match_dup 2)))
3055    (clobber (reg:GPR CA_REGNO))]
3056   "<MODE>mode == Pmode"
3057   "@
3058    sra<wd>i %0,%1,%p2\;addze. %0,%0
3059    #"
3060   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3061   [(parallel [(set (match_dup 0)
3062                    (div:GPR (match_dup 1)
3063                             (match_dup 2)))
3064               (clobber (reg:GPR CA_REGNO))])
3065    (set (match_dup 3)
3066         (compare:CC (match_dup 0)
3067                     (const_int 0)))]
3068   ""
3069   [(set_attr "type" "two")
3070    (set_attr "length" "8,12")
3071    (set_attr "cell_micro" "not")])
3073 (define_expand "mod<mode>3"
3074   [(set (match_operand:GPR 0 "gpc_reg_operand")
3075         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3076                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3077   ""
3079   int i;
3080   rtx temp1;
3081   rtx temp2;
3083   if (GET_CODE (operands[2]) != CONST_INT
3084       || INTVAL (operands[2]) <= 0
3085       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3086     {
3087       if (!TARGET_MODULO)
3088         FAIL;
3090       operands[2] = force_reg (<MODE>mode, operands[2]);
3091     }
3092   else
3093     {
3094       temp1 = gen_reg_rtx (<MODE>mode);
3095       temp2 = gen_reg_rtx (<MODE>mode);
3097       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3098       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3099       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3100       DONE;
3101     }
3104 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3105 ;; mod, prefer putting the result of mod into a different register
3106 (define_insn "*mod<mode>3"
3107   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3108         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3109                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3110   "TARGET_MODULO"
3111   "mods<wd> %0,%1,%2"
3112   [(set_attr "type" "div")
3113    (set_attr "size" "<bits>")])
3116 (define_insn "umod<mode>3"
3117   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3118         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3119                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3120   "TARGET_MODULO"
3121   "modu<wd> %0,%1,%2"
3122   [(set_attr "type" "div")
3123    (set_attr "size" "<bits>")])
3125 ;; On machines with modulo support, do a combined div/mod the old fashioned
3126 ;; method, since the multiply/subtract is faster than doing the mod instruction
3127 ;; after a divide.
3129 (define_peephole2
3130   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3131         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3132                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3133    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3134         (mod:GPR (match_dup 1)
3135                  (match_dup 2)))]
3136   "TARGET_MODULO
3137    && ! reg_mentioned_p (operands[0], operands[1])
3138    && ! reg_mentioned_p (operands[0], operands[2])
3139    && ! reg_mentioned_p (operands[3], operands[1])
3140    && ! reg_mentioned_p (operands[3], operands[2])"
3141   [(set (match_dup 0)
3142         (div:GPR (match_dup 1)
3143                  (match_dup 2)))
3144    (set (match_dup 3)
3145         (mult:GPR (match_dup 0)
3146                   (match_dup 2)))
3147    (set (match_dup 3)
3148         (minus:GPR (match_dup 1)
3149                    (match_dup 3)))])
3151 (define_peephole2
3152   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3153         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3154                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3155    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3156         (umod:GPR (match_dup 1)
3157                   (match_dup 2)))]
3158   "TARGET_MODULO
3159    && ! reg_mentioned_p (operands[0], operands[1])
3160    && ! reg_mentioned_p (operands[0], operands[2])
3161    && ! reg_mentioned_p (operands[3], operands[1])
3162    && ! reg_mentioned_p (operands[3], operands[2])"
3163   [(set (match_dup 0)
3164         (div:GPR (match_dup 1)
3165                  (match_dup 2)))
3166    (set (match_dup 3)
3167         (mult:GPR (match_dup 0)
3168                   (match_dup 2)))
3169    (set (match_dup 3)
3170         (minus:GPR (match_dup 1)
3171                    (match_dup 3)))])
3174 ;; Logical instructions
3175 ;; The logical instructions are mostly combined by using match_operator,
3176 ;; but the plain AND insns are somewhat different because there is no
3177 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3178 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3180 (define_expand "and<mode>3"
3181   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3182         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3183                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3184   ""
3186   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3187     {
3188       rs6000_split_logical (operands, AND, false, false, false);
3189       DONE;
3190     }
3192   if (CONST_INT_P (operands[2]))
3193     {
3194       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3195         {
3196           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3197           DONE;
3198         }
3200       if (logical_const_operand (operands[2], <MODE>mode)
3201           && rs6000_gen_cell_microcode)
3202         {
3203           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3204           DONE;
3205         }
3207       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3208         {
3209           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3210           DONE;
3211         }
3213       operands[2] = force_reg (<MODE>mode, operands[2]);
3214     }
3218 (define_insn "and<mode>3_imm"
3219   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3220         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3221                  (match_operand:GPR 2 "logical_const_operand" "n")))
3222    (clobber (match_scratch:CC 3 "=x"))]
3223   "rs6000_gen_cell_microcode
3224    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3225   "andi%e2. %0,%1,%u2"
3226   [(set_attr "type" "logical")
3227    (set_attr "dot" "yes")])
3229 (define_insn_and_split "*and<mode>3_imm_dot"
3230   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3231         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3232                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3233                     (const_int 0)))
3234    (clobber (match_scratch:GPR 0 "=r,r"))
3235    (clobber (match_scratch:CC 4 "=X,x"))]
3236   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3237    && rs6000_gen_cell_microcode
3238    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3239   "@
3240    andi%e2. %0,%1,%u2
3241    #"
3242   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3243   [(parallel [(set (match_dup 0)
3244                    (and:GPR (match_dup 1)
3245                             (match_dup 2)))
3246               (clobber (match_dup 4))])
3247    (set (match_dup 3)
3248         (compare:CC (match_dup 0)
3249                     (const_int 0)))]
3250   ""
3251   [(set_attr "type" "logical")
3252    (set_attr "dot" "yes")
3253    (set_attr "length" "4,8")])
3255 (define_insn_and_split "*and<mode>3_imm_dot2"
3256   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3257         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3258                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3259                     (const_int 0)))
3260    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3261         (and:GPR (match_dup 1)
3262                  (match_dup 2)))
3263    (clobber (match_scratch:CC 4 "=X,x"))]
3264   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3265    && rs6000_gen_cell_microcode
3266    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3267   "@
3268    andi%e2. %0,%1,%u2
3269    #"
3270   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3271   [(parallel [(set (match_dup 0)
3272                    (and:GPR (match_dup 1)
3273                             (match_dup 2)))
3274               (clobber (match_dup 4))])
3275    (set (match_dup 3)
3276         (compare:CC (match_dup 0)
3277                     (const_int 0)))]
3278   ""
3279   [(set_attr "type" "logical")
3280    (set_attr "dot" "yes")
3281    (set_attr "length" "4,8")])
3283 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3284   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3285         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3286                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3287                     (const_int 0)))
3288    (clobber (match_scratch:GPR 0 "=r,r"))]
3289   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3290    && rs6000_gen_cell_microcode
3291    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3292   "@
3293    andi%e2. %0,%1,%u2
3294    #"
3295   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3296   [(set (match_dup 0)
3297         (and:GPR (match_dup 1)
3298                  (match_dup 2)))
3299    (set (match_dup 3)
3300         (compare:CC (match_dup 0)
3301                     (const_int 0)))]
3302   ""
3303   [(set_attr "type" "logical")
3304    (set_attr "dot" "yes")
3305    (set_attr "length" "4,8")])
3307 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3308   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3309         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3310                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3311                     (const_int 0)))
3312    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3313         (and:GPR (match_dup 1)
3314                  (match_dup 2)))]
3315   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3316    && rs6000_gen_cell_microcode
3317    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3318   "@
3319    andi%e2. %0,%1,%u2
3320    #"
3321   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3322   [(set (match_dup 0)
3323         (and:GPR (match_dup 1)
3324                  (match_dup 2)))
3325    (set (match_dup 3)
3326         (compare:CC (match_dup 0)
3327                     (const_int 0)))]
3328   ""
3329   [(set_attr "type" "logical")
3330    (set_attr "dot" "yes")
3331    (set_attr "length" "4,8")])
3333 (define_insn "*and<mode>3_imm_dot_shifted"
3334   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3335         (compare:CC
3336           (and:GPR
3337             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3338                           (match_operand:SI 4 "const_int_operand" "n"))
3339             (match_operand:GPR 2 "const_int_operand" "n"))
3340           (const_int 0)))
3341    (clobber (match_scratch:GPR 0 "=r"))]
3342   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3343                                    << INTVAL (operands[4])),
3344                           DImode)
3345    && (<MODE>mode == Pmode
3346        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3347    && rs6000_gen_cell_microcode"
3349   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3350   return "andi%e2. %0,%1,%u2";
3352   [(set_attr "type" "logical")
3353    (set_attr "dot" "yes")])
3356 (define_insn "and<mode>3_mask"
3357   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3358         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3359                  (match_operand:GPR 2 "const_int_operand" "n")))]
3360   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3362   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3364   [(set_attr "type" "shift")])
3366 (define_insn_and_split "*and<mode>3_mask_dot"
3367   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3368         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3369                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3370                     (const_int 0)))
3371    (clobber (match_scratch:GPR 0 "=r,r"))]
3372   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3373    && rs6000_gen_cell_microcode
3374    && !logical_const_operand (operands[2], <MODE>mode)
3375    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3377   if (which_alternative == 0)
3378     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3379   else
3380     return "#";
3382   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3383   [(set (match_dup 0)
3384         (and:GPR (match_dup 1)
3385                  (match_dup 2)))
3386    (set (match_dup 3)
3387         (compare:CC (match_dup 0)
3388                     (const_int 0)))]
3389   ""
3390   [(set_attr "type" "shift")
3391    (set_attr "dot" "yes")
3392    (set_attr "length" "4,8")])
3394 (define_insn_and_split "*and<mode>3_mask_dot2"
3395   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3396         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3397                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3398                     (const_int 0)))
3399    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3400         (and:GPR (match_dup 1)
3401                  (match_dup 2)))]
3402   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3403    && rs6000_gen_cell_microcode
3404    && !logical_const_operand (operands[2], <MODE>mode)
3405    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3407   if (which_alternative == 0)
3408     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3409   else
3410     return "#";
3412   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3413   [(set (match_dup 0)
3414         (and:GPR (match_dup 1)
3415                  (match_dup 2)))
3416    (set (match_dup 3)
3417         (compare:CC (match_dup 0)
3418                     (const_int 0)))]
3419   ""
3420   [(set_attr "type" "shift")
3421    (set_attr "dot" "yes")
3422    (set_attr "length" "4,8")])
3425 (define_insn_and_split "*and<mode>3_2insn"
3426   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3427         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3428                  (match_operand:GPR 2 "const_int_operand" "n")))]
3429   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3430    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3431         || (logical_const_operand (operands[2], <MODE>mode)
3432             && rs6000_gen_cell_microcode))"
3433   "#"
3434   "&& 1"
3435   [(pc)]
3437   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3438   DONE;
3440   [(set_attr "type" "shift")
3441    (set_attr "length" "8")])
3443 (define_insn_and_split "*and<mode>3_2insn_dot"
3444   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3445         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3446                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3447                     (const_int 0)))
3448    (clobber (match_scratch:GPR 0 "=r,r"))]
3449   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3450    && rs6000_gen_cell_microcode
3451    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3452    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3453         || (logical_const_operand (operands[2], <MODE>mode)
3454             && rs6000_gen_cell_microcode))"
3455   "#"
3456   "&& reload_completed"
3457   [(pc)]
3459   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3460   DONE;
3462   [(set_attr "type" "shift")
3463    (set_attr "dot" "yes")
3464    (set_attr "length" "8,12")])
3466 (define_insn_and_split "*and<mode>3_2insn_dot2"
3467   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3468         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3469                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3470                     (const_int 0)))
3471    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3472         (and:GPR (match_dup 1)
3473                  (match_dup 2)))]
3474   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3475    && rs6000_gen_cell_microcode
3476    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3477    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3478         || (logical_const_operand (operands[2], <MODE>mode)
3479             && rs6000_gen_cell_microcode))"
3480   "#"
3481   "&& reload_completed"
3482   [(pc)]
3484   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3485   DONE;
3487   [(set_attr "type" "shift")
3488    (set_attr "dot" "yes")
3489    (set_attr "length" "8,12")])
3492 (define_expand "<code><mode>3"
3493   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3494         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3495                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3496   ""
3498   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3499     {
3500       rs6000_split_logical (operands, <CODE>, false, false, false);
3501       DONE;
3502     }
3504   if (non_logical_cint_operand (operands[2], <MODE>mode))
3505     {
3506       rtx tmp = ((!can_create_pseudo_p ()
3507                   || rtx_equal_p (operands[0], operands[1]))
3508                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3510       HOST_WIDE_INT value = INTVAL (operands[2]);
3511       HOST_WIDE_INT lo = value & 0xffff;
3512       HOST_WIDE_INT hi = value - lo;
3514       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3515       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3516       DONE;
3517     }
3519   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3520     operands[2] = force_reg (<MODE>mode, operands[2]);
3523 (define_split
3524   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3525         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3526                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3527   ""
3528   [(set (match_dup 3)
3529         (iorxor:GPR (match_dup 1)
3530                     (match_dup 4)))
3531    (set (match_dup 0)
3532         (iorxor:GPR (match_dup 3)
3533                     (match_dup 5)))]
3535   operands[3] = ((!can_create_pseudo_p ()
3536                   || rtx_equal_p (operands[0], operands[1]))
3537                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3539   HOST_WIDE_INT value = INTVAL (operands[2]);
3540   HOST_WIDE_INT lo = value & 0xffff;
3541   HOST_WIDE_INT hi = value - lo;
3543   operands[4] = GEN_INT (hi);
3544   operands[5] = GEN_INT (lo);
3547 (define_insn "*bool<mode>3_imm"
3548   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3549         (match_operator:GPR 3 "boolean_or_operator"
3550          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3551           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3552   ""
3553   "%q3i%e2 %0,%1,%u2"
3554   [(set_attr "type" "logical")])
3556 (define_insn "*bool<mode>3"
3557   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3558         (match_operator:GPR 3 "boolean_operator"
3559          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3560           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3561   ""
3562   "%q3 %0,%1,%2"
3563   [(set_attr "type" "logical")])
3565 (define_insn_and_split "*bool<mode>3_dot"
3566   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3567         (compare:CC (match_operator:GPR 3 "boolean_operator"
3568          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3569           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3570          (const_int 0)))
3571    (clobber (match_scratch:GPR 0 "=r,r"))]
3572   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3573   "@
3574    %q3. %0,%1,%2
3575    #"
3576   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3577   [(set (match_dup 0)
3578         (match_dup 3))
3579    (set (match_dup 4)
3580         (compare:CC (match_dup 0)
3581                     (const_int 0)))]
3582   ""
3583   [(set_attr "type" "logical")
3584    (set_attr "dot" "yes")
3585    (set_attr "length" "4,8")])
3587 (define_insn_and_split "*bool<mode>3_dot2"
3588   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3589         (compare:CC (match_operator:GPR 3 "boolean_operator"
3590          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3591           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3592          (const_int 0)))
3593    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3594         (match_dup 3))]
3595   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3596   "@
3597    %q3. %0,%1,%2
3598    #"
3599   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3600   [(set (match_dup 0)
3601         (match_dup 3))
3602    (set (match_dup 4)
3603         (compare:CC (match_dup 0)
3604                     (const_int 0)))]
3605   ""
3606   [(set_attr "type" "logical")
3607    (set_attr "dot" "yes")
3608    (set_attr "length" "4,8")])
3611 (define_insn "*boolc<mode>3"
3612   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3613         (match_operator:GPR 3 "boolean_operator"
3614          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3615           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3616   ""
3617   "%q3 %0,%1,%2"
3618   [(set_attr "type" "logical")])
3620 (define_insn_and_split "*boolc<mode>3_dot"
3621   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3622         (compare:CC (match_operator:GPR 3 "boolean_operator"
3623          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3624           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3625          (const_int 0)))
3626    (clobber (match_scratch:GPR 0 "=r,r"))]
3627   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3628   "@
3629    %q3. %0,%1,%2
3630    #"
3631   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3632   [(set (match_dup 0)
3633         (match_dup 3))
3634    (set (match_dup 4)
3635         (compare:CC (match_dup 0)
3636                     (const_int 0)))]
3637   ""
3638   [(set_attr "type" "logical")
3639    (set_attr "dot" "yes")
3640    (set_attr "length" "4,8")])
3642 (define_insn_and_split "*boolc<mode>3_dot2"
3643   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3644         (compare:CC (match_operator:GPR 3 "boolean_operator"
3645          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3646           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3647          (const_int 0)))
3648    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3649         (match_dup 3))]
3650   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3651   "@
3652    %q3. %0,%1,%2
3653    #"
3654   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3655   [(set (match_dup 0)
3656         (match_dup 3))
3657    (set (match_dup 4)
3658         (compare:CC (match_dup 0)
3659                     (const_int 0)))]
3660   ""
3661   [(set_attr "type" "logical")
3662    (set_attr "dot" "yes")
3663    (set_attr "length" "4,8")])
3666 (define_insn "*boolcc<mode>3"
3667   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3668         (match_operator:GPR 3 "boolean_operator"
3669          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3670           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3671   ""
3672   "%q3 %0,%1,%2"
3673   [(set_attr "type" "logical")])
3675 (define_insn_and_split "*boolcc<mode>3_dot"
3676   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3677         (compare:CC (match_operator:GPR 3 "boolean_operator"
3678          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3679           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3680          (const_int 0)))
3681    (clobber (match_scratch:GPR 0 "=r,r"))]
3682   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3683   "@
3684    %q3. %0,%1,%2
3685    #"
3686   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3687   [(set (match_dup 0)
3688         (match_dup 3))
3689    (set (match_dup 4)
3690         (compare:CC (match_dup 0)
3691                     (const_int 0)))]
3692   ""
3693   [(set_attr "type" "logical")
3694    (set_attr "dot" "yes")
3695    (set_attr "length" "4,8")])
3697 (define_insn_and_split "*boolcc<mode>3_dot2"
3698   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3699         (compare:CC (match_operator:GPR 3 "boolean_operator"
3700          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3701           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3702          (const_int 0)))
3703    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3704         (match_dup 3))]
3705   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3706   "@
3707    %q3. %0,%1,%2
3708    #"
3709   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3710   [(set (match_dup 0)
3711         (match_dup 3))
3712    (set (match_dup 4)
3713         (compare:CC (match_dup 0)
3714                     (const_int 0)))]
3715   ""
3716   [(set_attr "type" "logical")
3717    (set_attr "dot" "yes")
3718    (set_attr "length" "4,8")])
3721 ;; TODO: Should have dots of this as well.
3722 (define_insn "*eqv<mode>3"
3723   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3724         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3725                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3726   ""
3727   "eqv %0,%1,%2"
3728   [(set_attr "type" "logical")])
3730 ;; Rotate-and-mask and insert.
3732 (define_insn "*rotl<mode>3_mask"
3733   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3734         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3735                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3736                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3737                  (match_operand:GPR 3 "const_int_operand" "n")))]
3738   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3740   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3742   [(set_attr "type" "shift")
3743    (set_attr "maybe_var_shift" "yes")])
3745 (define_insn_and_split "*rotl<mode>3_mask_dot"
3746   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3747         (compare:CC
3748           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3749                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3750                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3751                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3752           (const_int 0)))
3753    (clobber (match_scratch:GPR 0 "=r,r"))]
3754   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3755    && rs6000_gen_cell_microcode
3756    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3758   if (which_alternative == 0)
3759     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3760   else
3761     return "#";
3763   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3764   [(set (match_dup 0)
3765         (and:GPR (match_dup 4)
3766                  (match_dup 3)))
3767    (set (match_dup 5)
3768         (compare:CC (match_dup 0)
3769                     (const_int 0)))]
3770   ""
3771   [(set_attr "type" "shift")
3772    (set_attr "maybe_var_shift" "yes")
3773    (set_attr "dot" "yes")
3774    (set_attr "length" "4,8")])
3776 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3777   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3778         (compare:CC
3779           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3780                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3781                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3782                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3783           (const_int 0)))
3784    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3785         (and:GPR (match_dup 4)
3786                  (match_dup 3)))]
3787   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3788    && rs6000_gen_cell_microcode
3789    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3791   if (which_alternative == 0)
3792     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3793   else
3794     return "#";
3796   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3797   [(set (match_dup 0)
3798         (and:GPR (match_dup 4)
3799                  (match_dup 3)))
3800    (set (match_dup 5)
3801         (compare:CC (match_dup 0)
3802                     (const_int 0)))]
3803   ""
3804   [(set_attr "type" "shift")
3805    (set_attr "maybe_var_shift" "yes")
3806    (set_attr "dot" "yes")
3807    (set_attr "length" "4,8")])
3809 ; Special case for less-than-0.  We can do it with just one machine
3810 ; instruction, but the generic optimizers do not realise it is cheap.
3811 (define_insn "*lt0_disi"
3812   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3813         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3814                (const_int 0)))]
3815   "TARGET_POWERPC64"
3816   "rlwinm %0,%1,1,31,31"
3817   [(set_attr "type" "shift")])
3821 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3822 ; both are an AND so are the same precedence).
3823 (define_insn "*rotl<mode>3_insert"
3824   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3825         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3826                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3827                             (match_operand:SI 2 "const_int_operand" "n")])
3828                           (match_operand:GPR 3 "const_int_operand" "n"))
3829                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3830                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3831   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3832    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3834   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3836   [(set_attr "type" "insert")])
3837 ; FIXME: this needs an attr "size", so that the scheduler can see the
3838 ; difference between rlwimi and rldimi.  We also might want dot forms,
3839 ; but not for rlwimi on POWER4 and similar processors.
3841 (define_insn "*rotl<mode>3_insert_2"
3842   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3843         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3844                           (match_operand:GPR 6 "const_int_operand" "n"))
3845                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3846                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3847                             (match_operand:SI 2 "const_int_operand" "n")])
3848                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3849   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3850    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3852   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3854   [(set_attr "type" "insert")])
3856 ; There are also some forms without one of the ANDs.
3857 (define_insn "*rotl<mode>3_insert_3"
3858   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3859         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3860                           (match_operand:GPR 4 "const_int_operand" "n"))
3861                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3862                              (match_operand:SI 2 "const_int_operand" "n"))))]
3863   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3865   if (<MODE>mode == SImode)
3866     return "rlwimi %0,%1,%h2,0,31-%h2";
3867   else
3868     return "rldimi %0,%1,%H2,0";
3870   [(set_attr "type" "insert")])
3872 (define_insn "*rotl<mode>3_insert_4"
3873   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3874         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3875                           (match_operand:GPR 4 "const_int_operand" "n"))
3876                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3877                                (match_operand:SI 2 "const_int_operand" "n"))))]
3878   "<MODE>mode == SImode &&
3879    GET_MODE_PRECISION (<MODE>mode)
3880    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3882   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3883                          - INTVAL (operands[2]));
3884   if (<MODE>mode == SImode)
3885     return "rlwimi %0,%1,%h2,32-%h2,31";
3886   else
3887     return "rldimi %0,%1,%H2,64-%H2";
3889   [(set_attr "type" "insert")])
3891 (define_insn "*rotlsi3_insert_5"
3892   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3893         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3894                         (match_operand:SI 2 "const_int_operand" "n,n"))
3895                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3896                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3897   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3898    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3899    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3900   "@
3901    rlwimi %0,%3,0,%4
3902    rlwimi %0,%1,0,%2"
3903   [(set_attr "type" "insert")])
3905 (define_insn "*rotldi3_insert_6"
3906   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3907         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3908                         (match_operand:DI 2 "const_int_operand" "n"))
3909                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3910                         (match_operand:DI 4 "const_int_operand" "n"))))]
3911   "exact_log2 (-UINTVAL (operands[2])) > 0
3912    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3914   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3915   return "rldimi %0,%3,0,%5";
3917   [(set_attr "type" "insert")
3918    (set_attr "size" "64")])
3920 (define_insn "*rotldi3_insert_7"
3921   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3922         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3923                         (match_operand:DI 4 "const_int_operand" "n"))
3924                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3925                         (match_operand:DI 2 "const_int_operand" "n"))))]
3926   "exact_log2 (-UINTVAL (operands[2])) > 0
3927    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3929   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3930   return "rldimi %0,%3,0,%5";
3932   [(set_attr "type" "insert")
3933    (set_attr "size" "64")])
3936 ; This handles the important case of multiple-precision shifts.  There is
3937 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3938 (define_split
3939   [(set (match_operand:GPR 0 "gpc_reg_operand")
3940         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3941                              (match_operand:SI 3 "const_int_operand"))
3942                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3943                                (match_operand:SI 4 "const_int_operand"))))]
3944   "can_create_pseudo_p ()
3945    && INTVAL (operands[3]) + INTVAL (operands[4])
3946       >= GET_MODE_PRECISION (<MODE>mode)"
3947   [(set (match_dup 5)
3948         (lshiftrt:GPR (match_dup 2)
3949                       (match_dup 4)))
3950    (set (match_dup 0)
3951         (ior:GPR (and:GPR (match_dup 5)
3952                           (match_dup 6))
3953                  (ashift:GPR (match_dup 1)
3954                              (match_dup 3))))]
3956   unsigned HOST_WIDE_INT mask = 1;
3957   mask = (mask << INTVAL (operands[3])) - 1;
3958   operands[5] = gen_reg_rtx (<MODE>mode);
3959   operands[6] = GEN_INT (mask);
3962 (define_split
3963   [(set (match_operand:GPR 0 "gpc_reg_operand")
3964         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3965                                (match_operand:SI 4 "const_int_operand"))
3966                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3967                              (match_operand:SI 3 "const_int_operand"))))]
3968   "can_create_pseudo_p ()
3969    && INTVAL (operands[3]) + INTVAL (operands[4])
3970       >= GET_MODE_PRECISION (<MODE>mode)"
3971   [(set (match_dup 5)
3972         (lshiftrt:GPR (match_dup 2)
3973                       (match_dup 4)))
3974    (set (match_dup 0)
3975         (ior:GPR (and:GPR (match_dup 5)
3976                           (match_dup 6))
3977                  (ashift:GPR (match_dup 1)
3978                              (match_dup 3))))]
3980   unsigned HOST_WIDE_INT mask = 1;
3981   mask = (mask << INTVAL (operands[3])) - 1;
3982   operands[5] = gen_reg_rtx (<MODE>mode);
3983   operands[6] = GEN_INT (mask);
3987 ; Another important case is setting some bits to 1; we can do that with
3988 ; an insert instruction, in many cases.
3989 (define_insn_and_split "*ior<mode>_mask"
3990   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3991         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3992                  (match_operand:GPR 2 "const_int_operand" "n")))
3993    (clobber (match_scratch:GPR 3 "=r"))]
3994   "!logical_const_operand (operands[2], <MODE>mode)
3995    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3996   "#"
3997   "&& 1"
3998   [(set (match_dup 3)
3999         (const_int -1))
4000    (set (match_dup 0)
4001         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4002                                       (match_dup 4))
4003                           (match_dup 2))
4004                  (and:GPR (match_dup 1)
4005                           (match_dup 5))))]
4007   int nb, ne;
4008   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4009   if (GET_CODE (operands[3]) == SCRATCH)
4010     operands[3] = gen_reg_rtx (<MODE>mode);
4011   operands[4] = GEN_INT (ne);
4012   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4014   [(set_attr "type" "two")
4015    (set_attr "length" "8")])
4018 ;; Now the simple shifts.
4020 (define_insn "rotl<mode>3"
4021   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4022         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4023                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4024   ""
4025   "rotl<wd>%I2 %0,%1,%<hH>2"
4026   [(set_attr "type" "shift")
4027    (set_attr "maybe_var_shift" "yes")])
4029 (define_insn "*rotlsi3_64"
4030   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4031         (zero_extend:DI
4032             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4033                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4034   "TARGET_POWERPC64"
4035   "rotlw%I2 %0,%1,%h2"
4036   [(set_attr "type" "shift")
4037    (set_attr "maybe_var_shift" "yes")])
4039 (define_insn_and_split "*rotl<mode>3_dot"
4040   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4041         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4042                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4043                     (const_int 0)))
4044    (clobber (match_scratch:GPR 0 "=r,r"))]
4045   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4046   "@
4047    rotl<wd>%I2. %0,%1,%<hH>2
4048    #"
4049   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4050   [(set (match_dup 0)
4051         (rotate:GPR (match_dup 1)
4052                     (match_dup 2)))
4053    (set (match_dup 3)
4054         (compare:CC (match_dup 0)
4055                     (const_int 0)))]
4056   ""
4057   [(set_attr "type" "shift")
4058    (set_attr "maybe_var_shift" "yes")
4059    (set_attr "dot" "yes")
4060    (set_attr "length" "4,8")])
4062 (define_insn_and_split "*rotl<mode>3_dot2"
4063   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4064         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4065                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4066                     (const_int 0)))
4067    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4068         (rotate:GPR (match_dup 1)
4069                     (match_dup 2)))]
4070   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4071   "@
4072    rotl<wd>%I2. %0,%1,%<hH>2
4073    #"
4074   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4075   [(set (match_dup 0)
4076         (rotate:GPR (match_dup 1)
4077                     (match_dup 2)))
4078    (set (match_dup 3)
4079         (compare:CC (match_dup 0)
4080                     (const_int 0)))]
4081   ""
4082   [(set_attr "type" "shift")
4083    (set_attr "maybe_var_shift" "yes")
4084    (set_attr "dot" "yes")
4085    (set_attr "length" "4,8")])
4088 (define_insn "ashl<mode>3"
4089   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4090         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4091                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4092   ""
4093   "sl<wd>%I2 %0,%1,%<hH>2"
4094   [(set_attr "type" "shift")
4095    (set_attr "maybe_var_shift" "yes")])
4097 (define_insn "*ashlsi3_64"
4098   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4099         (zero_extend:DI
4100             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4101                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4102   "TARGET_POWERPC64"
4103   "slw%I2 %0,%1,%h2"
4104   [(set_attr "type" "shift")
4105    (set_attr "maybe_var_shift" "yes")])
4107 (define_insn_and_split "*ashl<mode>3_dot"
4108   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4109         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4110                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4111                     (const_int 0)))
4112    (clobber (match_scratch:GPR 0 "=r,r"))]
4113   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4114   "@
4115    sl<wd>%I2. %0,%1,%<hH>2
4116    #"
4117   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4118   [(set (match_dup 0)
4119         (ashift:GPR (match_dup 1)
4120                     (match_dup 2)))
4121    (set (match_dup 3)
4122         (compare:CC (match_dup 0)
4123                     (const_int 0)))]
4124   ""
4125   [(set_attr "type" "shift")
4126    (set_attr "maybe_var_shift" "yes")
4127    (set_attr "dot" "yes")
4128    (set_attr "length" "4,8")])
4130 (define_insn_and_split "*ashl<mode>3_dot2"
4131   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4132         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4133                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4134                     (const_int 0)))
4135    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4136         (ashift:GPR (match_dup 1)
4137                     (match_dup 2)))]
4138   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4139   "@
4140    sl<wd>%I2. %0,%1,%<hH>2
4141    #"
4142   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4143   [(set (match_dup 0)
4144         (ashift:GPR (match_dup 1)
4145                     (match_dup 2)))
4146    (set (match_dup 3)
4147         (compare:CC (match_dup 0)
4148                     (const_int 0)))]
4149   ""
4150   [(set_attr "type" "shift")
4151    (set_attr "maybe_var_shift" "yes")
4152    (set_attr "dot" "yes")
4153    (set_attr "length" "4,8")])
4155 ;; Pretend we have a memory form of extswsli until register allocation is done
4156 ;; so that we use LWZ to load the value from memory, instead of LWA.
4157 (define_insn_and_split "ashdi3_extswsli"
4158   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4159         (ashift:DI
4160          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4161          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4162   "TARGET_EXTSWSLI"
4163   "@
4164    extswsli %0,%1,%2
4165    #"
4166   "&& reload_completed && MEM_P (operands[1])"
4167   [(set (match_dup 3)
4168         (match_dup 1))
4169    (set (match_dup 0)
4170         (ashift:DI (sign_extend:DI (match_dup 3))
4171                    (match_dup 2)))]
4173   operands[3] = gen_lowpart (SImode, operands[0]);
4175   [(set_attr "type" "shift")
4176    (set_attr "maybe_var_shift" "no")])
4179 (define_insn_and_split "ashdi3_extswsli_dot"
4180   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4181         (compare:CC
4182          (ashift:DI
4183           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4184           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4185          (const_int 0)))
4186    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4187   "TARGET_EXTSWSLI"
4188   "@
4189    extswsli. %0,%1,%2
4190    #
4191    #
4192    #"
4193   "&& reload_completed
4194    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4195        || memory_operand (operands[1], SImode))"
4196   [(pc)]
4198   rtx dest = operands[0];
4199   rtx src = operands[1];
4200   rtx shift = operands[2];
4201   rtx cr = operands[3];
4202   rtx src2;
4204   if (!MEM_P (src))
4205     src2 = src;
4206   else
4207     {
4208       src2 = gen_lowpart (SImode, dest);
4209       emit_move_insn (src2, src);
4210     }
4212   if (REGNO (cr) == CR0_REGNO)
4213     {
4214       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4215       DONE;
4216     }
4218   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4219   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4220   DONE;
4222   [(set_attr "type" "shift")
4223    (set_attr "maybe_var_shift" "no")
4224    (set_attr "dot" "yes")
4225    (set_attr "length" "4,8,8,12")])
4227 (define_insn_and_split "ashdi3_extswsli_dot2"
4228   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4229         (compare:CC
4230          (ashift:DI
4231           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4232           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4233          (const_int 0)))
4234    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4235         (ashift:DI (sign_extend:DI (match_dup 1))
4236                    (match_dup 2)))]
4237   "TARGET_EXTSWSLI"
4238   "@
4239    extswsli. %0,%1,%2
4240    #
4241    #
4242    #"
4243   "&& reload_completed
4244    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4245        || memory_operand (operands[1], SImode))"
4246   [(pc)]
4248   rtx dest = operands[0];
4249   rtx src = operands[1];
4250   rtx shift = operands[2];
4251   rtx cr = operands[3];
4252   rtx src2;
4254   if (!MEM_P (src))
4255     src2 = src;
4256   else
4257     {
4258       src2 = gen_lowpart (SImode, dest);
4259       emit_move_insn (src2, src);
4260     }
4262   if (REGNO (cr) == CR0_REGNO)
4263     {
4264       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4265       DONE;
4266     }
4268   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4269   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4270   DONE;
4272   [(set_attr "type" "shift")
4273    (set_attr "maybe_var_shift" "no")
4274    (set_attr "dot" "yes")
4275    (set_attr "length" "4,8,8,12")])
4277 (define_insn "lshr<mode>3"
4278   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4279         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4280                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4281   ""
4282   "sr<wd>%I2 %0,%1,%<hH>2"
4283   [(set_attr "type" "shift")
4284    (set_attr "maybe_var_shift" "yes")])
4286 (define_insn "*lshrsi3_64"
4287   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4288         (zero_extend:DI
4289             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4290                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4291   "TARGET_POWERPC64"
4292   "srw%I2 %0,%1,%h2"
4293   [(set_attr "type" "shift")
4294    (set_attr "maybe_var_shift" "yes")])
4296 (define_insn_and_split "*lshr<mode>3_dot"
4297   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4298         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4299                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4300                     (const_int 0)))
4301    (clobber (match_scratch:GPR 0 "=r,r"))]
4302   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4303   "@
4304    sr<wd>%I2. %0,%1,%<hH>2
4305    #"
4306   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4307   [(set (match_dup 0)
4308         (lshiftrt:GPR (match_dup 1)
4309                       (match_dup 2)))
4310    (set (match_dup 3)
4311         (compare:CC (match_dup 0)
4312                     (const_int 0)))]
4313   ""
4314   [(set_attr "type" "shift")
4315    (set_attr "maybe_var_shift" "yes")
4316    (set_attr "dot" "yes")
4317    (set_attr "length" "4,8")])
4319 (define_insn_and_split "*lshr<mode>3_dot2"
4320   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4321         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4322                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4323                     (const_int 0)))
4324    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4325         (lshiftrt:GPR (match_dup 1)
4326                       (match_dup 2)))]
4327   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4328   "@
4329    sr<wd>%I2. %0,%1,%<hH>2
4330    #"
4331   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4332   [(set (match_dup 0)
4333         (lshiftrt:GPR (match_dup 1)
4334                       (match_dup 2)))
4335    (set (match_dup 3)
4336         (compare:CC (match_dup 0)
4337                     (const_int 0)))]
4338   ""
4339   [(set_attr "type" "shift")
4340    (set_attr "maybe_var_shift" "yes")
4341    (set_attr "dot" "yes")
4342    (set_attr "length" "4,8")])
4345 (define_insn "ashr<mode>3"
4346   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4347         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4348                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4349    (clobber (reg:GPR CA_REGNO))]
4350   ""
4351   "sra<wd>%I2 %0,%1,%<hH>2"
4352   [(set_attr "type" "shift")
4353    (set_attr "maybe_var_shift" "yes")])
4355 (define_insn "*ashrsi3_64"
4356   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4357         (sign_extend:DI
4358             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4359                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4360    (clobber (reg:SI CA_REGNO))]
4361   "TARGET_POWERPC64"
4362   "sraw%I2 %0,%1,%h2"
4363   [(set_attr "type" "shift")
4364    (set_attr "maybe_var_shift" "yes")])
4366 (define_insn_and_split "*ashr<mode>3_dot"
4367   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4368         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4369                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4370                     (const_int 0)))
4371    (clobber (match_scratch:GPR 0 "=r,r"))
4372    (clobber (reg:GPR CA_REGNO))]
4373   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4374   "@
4375    sra<wd>%I2. %0,%1,%<hH>2
4376    #"
4377   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4378   [(parallel [(set (match_dup 0)
4379                    (ashiftrt:GPR (match_dup 1)
4380                                  (match_dup 2)))
4381               (clobber (reg:GPR CA_REGNO))])
4382    (set (match_dup 3)
4383         (compare:CC (match_dup 0)
4384                     (const_int 0)))]
4385   ""
4386   [(set_attr "type" "shift")
4387    (set_attr "maybe_var_shift" "yes")
4388    (set_attr "dot" "yes")
4389    (set_attr "length" "4,8")])
4391 (define_insn_and_split "*ashr<mode>3_dot2"
4392   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4393         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4394                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4395                     (const_int 0)))
4396    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4397         (ashiftrt:GPR (match_dup 1)
4398                       (match_dup 2)))
4399    (clobber (reg:GPR CA_REGNO))]
4400   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4401   "@
4402    sra<wd>%I2. %0,%1,%<hH>2
4403    #"
4404   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4405   [(parallel [(set (match_dup 0)
4406                    (ashiftrt:GPR (match_dup 1)
4407                                  (match_dup 2)))
4408               (clobber (reg:GPR CA_REGNO))])
4409    (set (match_dup 3)
4410         (compare:CC (match_dup 0)
4411                     (const_int 0)))]
4412   ""
4413   [(set_attr "type" "shift")
4414    (set_attr "maybe_var_shift" "yes")
4415    (set_attr "dot" "yes")
4416    (set_attr "length" "4,8")])
4418 ;; Builtins to replace a division to generate FRE reciprocal estimate
4419 ;; instructions and the necessary fixup instructions
4420 (define_expand "recip<mode>3"
4421   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4422    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4423    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4424   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4426    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4427    DONE;
4430 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4431 ;; hardware division.  This is only done before register allocation and with
4432 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4433 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4434 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4435 (define_split
4436   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4437         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4438                     (match_operand 2 "gpc_reg_operand" "")))]
4439   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4440    && can_create_pseudo_p () && flag_finite_math_only
4441    && !flag_trapping_math && flag_reciprocal_math"
4442   [(const_int 0)]
4444   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4445   DONE;
4448 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4449 ;; appropriate fixup.
4450 (define_expand "rsqrt<mode>2"
4451   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4452    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4453   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4455   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4456   DONE;
4459 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4460 ;; modes here, and also add in conditional vsx/power8-vector support to access
4461 ;; values in the traditional Altivec registers if the appropriate
4462 ;; -mupper-regs-{df,sf} option is enabled.
4464 (define_expand "abs<mode>2"
4465   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4466         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4467   "TARGET_<MODE>_INSN"
4468   "")
4470 (define_insn "*abs<mode>2_fpr"
4471   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4472         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4473   "TARGET_<MODE>_FPR"
4474   "@
4475    fabs %0,%1
4476    xsabsdp %x0,%x1"
4477   [(set_attr "type" "fpsimple")
4478    (set_attr "fp_type" "fp_addsub_<Fs>")])
4480 (define_insn "*nabs<mode>2_fpr"
4481   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4482         (neg:SFDF
4483          (abs:SFDF
4484           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4485   "TARGET_<MODE>_FPR"
4486   "@
4487    fnabs %0,%1
4488    xsnabsdp %x0,%x1"
4489   [(set_attr "type" "fpsimple")
4490    (set_attr "fp_type" "fp_addsub_<Fs>")])
4492 (define_expand "neg<mode>2"
4493   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4494         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4495   "TARGET_<MODE>_INSN"
4496   "")
4498 (define_insn "*neg<mode>2_fpr"
4499   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4500         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4501   "TARGET_<MODE>_FPR"
4502   "@
4503    fneg %0,%1
4504    xsnegdp %x0,%x1"
4505   [(set_attr "type" "fpsimple")
4506    (set_attr "fp_type" "fp_addsub_<Fs>")])
4508 (define_expand "add<mode>3"
4509   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4510         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4511                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4512   "TARGET_<MODE>_INSN"
4513   "")
4515 (define_insn "*add<mode>3_fpr"
4516   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4517         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4518                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4519   "TARGET_<MODE>_FPR"
4520   "@
4521    fadd<Ftrad> %0,%1,%2
4522    xsadd<Fvsx> %x0,%x1,%x2"
4523   [(set_attr "type" "fp")
4524    (set_attr "fp_type" "fp_addsub_<Fs>")])
4526 (define_expand "sub<mode>3"
4527   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4528         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4529                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4530   "TARGET_<MODE>_INSN"
4531   "")
4533 (define_insn "*sub<mode>3_fpr"
4534   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4535         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4536                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4537   "TARGET_<MODE>_FPR"
4538   "@
4539    fsub<Ftrad> %0,%1,%2
4540    xssub<Fvsx> %x0,%x1,%x2"
4541   [(set_attr "type" "fp")
4542    (set_attr "fp_type" "fp_addsub_<Fs>")])
4544 (define_expand "mul<mode>3"
4545   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4546         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4547                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4548   "TARGET_<MODE>_INSN"
4549   "")
4551 (define_insn "*mul<mode>3_fpr"
4552   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4553         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4554                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4555   "TARGET_<MODE>_FPR"
4556   "@
4557    fmul<Ftrad> %0,%1,%2
4558    xsmul<Fvsx> %x0,%x1,%x2"
4559   [(set_attr "type" "dmul")
4560    (set_attr "fp_type" "fp_mul_<Fs>")])
4562 (define_expand "div<mode>3"
4563   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4564         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4565                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4566   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4568   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4569       && can_create_pseudo_p () && flag_finite_math_only
4570       && !flag_trapping_math && flag_reciprocal_math)
4571     {
4572       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4573       DONE;
4574     }
4577 (define_insn "*div<mode>3_fpr"
4578   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4579         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4580                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4581   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4582   "@
4583    fdiv<Ftrad> %0,%1,%2
4584    xsdiv<Fvsx> %x0,%x1,%x2"
4585   [(set_attr "type" "<Fs>div")
4586    (set_attr "fp_type" "fp_div_<Fs>")])
4588 (define_insn "*sqrt<mode>2_internal"
4589   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4590         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4591   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4592    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4593   "@
4594    fsqrt<Ftrad> %0,%1
4595    xssqrt<Fvsx> %x0,%x1"
4596   [(set_attr "type" "<Fs>sqrt")
4597    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4599 (define_expand "sqrt<mode>2"
4600   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4601         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4602   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4603    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4605   if (<MODE>mode == SFmode
4606       && TARGET_RECIP_PRECISION
4607       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4608       && !optimize_function_for_size_p (cfun)
4609       && flag_finite_math_only && !flag_trapping_math
4610       && flag_unsafe_math_optimizations)
4611     {
4612       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4613       DONE;
4614     }
4617 ;; Floating point reciprocal approximation
4618 (define_insn "fre<Fs>"
4619   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4620         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4621                      UNSPEC_FRES))]
4622   "TARGET_<FFRE>"
4623   "@
4624    fre<Ftrad> %0,%1
4625    xsre<Fvsx> %x0,%x1"
4626   [(set_attr "type" "fp")])
4628 (define_insn "*rsqrt<mode>2"
4629   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4630         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4631                      UNSPEC_RSQRT))]
4632   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4633   "@
4634    frsqrte<Ftrad> %0,%1
4635    xsrsqrte<Fvsx> %x0,%x1"
4636   [(set_attr "type" "fp")])
4638 ;; Floating point comparisons
4639 (define_insn "*cmp<mode>_fpr"
4640   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4641         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4642                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4643   "TARGET_<MODE>_FPR"
4644   "@
4645    fcmpu %0,%1,%2
4646    xscmpudp %0,%x1,%x2"
4647   [(set_attr "type" "fpcompare")])
4649 ;; Floating point conversions
4650 (define_expand "extendsfdf2"
4651   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4652         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4653   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4654   "")
4656 (define_insn_and_split "*extendsfdf2_fpr"
4657   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4658         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4659   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4660   "@
4661    #
4662    fmr %0,%1
4663    lfs%U1%X1 %0,%1
4664    #
4665    xscpsgndp %x0,%x1,%x1
4666    lxsspx %x0,%y1
4667    lxssp %0,%1"
4668   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4669   [(const_int 0)]
4671   emit_note (NOTE_INSN_DELETED);
4672   DONE;
4674   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4676 (define_expand "truncdfsf2"
4677   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4678         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4679   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4680   "")
4682 (define_insn "*truncdfsf2_fpr"
4683   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4684         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4685   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4686   "@
4687    frsp %0,%1
4688    xsrsp %x0,%x1"
4689   [(set_attr "type" "fp")])
4691 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4692 ;; builtins.c and optabs.c that are not correct for IBM long double
4693 ;; when little-endian.
4694 (define_expand "signbit<mode>2"
4695   [(set (match_dup 2)
4696         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4697    (set (match_dup 3)
4698         (subreg:DI (match_dup 2) 0))
4699    (set (match_dup 4)
4700         (match_dup 5))
4701    (set (match_operand:SI 0 "gpc_reg_operand" "")
4702         (match_dup 6))]
4703   "TARGET_HARD_FLOAT
4704    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4705    && (!FLOAT128_IEEE_P (<MODE>mode)
4706        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4708   if (FLOAT128_IEEE_P (<MODE>mode))
4709     {
4710       if (<MODE>mode == KFmode)
4711         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4712       else if (<MODE>mode == TFmode)
4713         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4714       else
4715         gcc_unreachable ();
4716       DONE;
4717     }
4718   operands[2] = gen_reg_rtx (DFmode);
4719   operands[3] = gen_reg_rtx (DImode);
4720   if (TARGET_POWERPC64)
4721     {
4722       operands[4] = gen_reg_rtx (DImode);
4723       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4724       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4725                                     WORDS_BIG_ENDIAN ? 4 : 0);
4726     }
4727   else
4728     {
4729       operands[4] = gen_reg_rtx (SImode);
4730       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4731                                     WORDS_BIG_ENDIAN ? 0 : 4);
4732       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4733     }
4736 (define_expand "copysign<mode>3"
4737   [(set (match_dup 3)
4738         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4739    (set (match_dup 4)
4740         (neg:SFDF (abs:SFDF (match_dup 1))))
4741    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4742         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4743                                (match_dup 5))
4744                          (match_dup 3)
4745                          (match_dup 4)))]
4746   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4747    && ((TARGET_PPC_GFXOPT
4748         && !HONOR_NANS (<MODE>mode)
4749         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4750        || TARGET_CMPB
4751        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4753   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4754     {
4755       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4756                                              operands[2]));
4757       DONE;
4758     }
4760    operands[3] = gen_reg_rtx (<MODE>mode);
4761    operands[4] = gen_reg_rtx (<MODE>mode);
4762    operands[5] = CONST0_RTX (<MODE>mode);
4763   })
4765 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4766 ;; and load.
4767 (define_insn_and_split "signbit<mode>2_dm"
4768   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4769         (unspec:SI
4770          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4771          UNSPEC_SIGNBIT))]
4772   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4773   "#"
4774   "&& reload_completed"
4775   [(const_int 0)]
4777   rs6000_split_signbit (operands[0], operands[1]);
4778   DONE;
4780  [(set_attr "length" "8,8,4")
4781   (set_attr "type" "mftgpr,load,integer")])
4783 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4784   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4785         (any_extend:DI
4786          (unspec:SI
4787           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4788           UNSPEC_SIGNBIT)))]
4789   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4790   "#"
4791   "&& reload_completed"
4792   [(const_int 0)]
4794   rs6000_split_signbit (operands[0], operands[1]);
4795   DONE;
4797  [(set_attr "length" "8,8,4")
4798   (set_attr "type" "mftgpr,load,integer")])
4800 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4801 ;; point types, which makes normal SUBREG's problematical. Instead use a
4802 ;; special pattern to avoid using a normal movdi.
4803 (define_insn "signbit<mode>2_dm2"
4804   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4805         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4806                     (const_int 0)]
4807                    UNSPEC_SIGNBIT))]
4808   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4809   "mfvsrd %0,%x1"
4810  [(set_attr "type" "mftgpr")])
4813 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4814 ;; compiler from optimizing -0.0
4815 (define_insn "copysign<mode>3_fcpsgn"
4816   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4817         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4818                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4819                      UNSPEC_COPYSIGN))]
4820   "TARGET_<MODE>_FPR && TARGET_CMPB"
4821   "@
4822    fcpsgn %0,%2,%1
4823    xscpsgndp %x0,%x2,%x1"
4824   [(set_attr "type" "fpsimple")])
4826 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4827 ;; fsel instruction and some auxiliary computations.  Then we just have a
4828 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4829 ;; combine.
4830 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4831 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4832 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4833 ;; define_splits to make them if made by combine.  On VSX machines we have the
4834 ;; min/max instructions.
4836 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4837 ;; to allow either DF/SF to use only traditional registers.
4839 (define_expand "s<minmax><mode>3"
4840   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4841         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4842                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4843   "TARGET_MINMAX_<MODE>"
4845   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4846   DONE;
4849 (define_insn "*s<minmax><mode>3_vsx"
4850   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4851         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4852                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4853   "TARGET_VSX && TARGET_<MODE>_FPR"
4855   return (TARGET_P9_MINMAX
4856           ? "xs<minmax>cdp %x0,%x1,%x2"
4857           : "xs<minmax>dp %x0,%x1,%x2");
4859   [(set_attr "type" "fp")])
4861 ;; The conditional move instructions allow us to perform max and min operations
4862 ;; even when we don't have the appropriate max/min instruction using the FSEL
4863 ;; instruction.
4865 (define_insn_and_split "*s<minmax><mode>3_fpr"
4866   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4867         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4868                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4869   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4870   "#"
4871   "&& 1"
4872   [(const_int 0)]
4874   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4875   DONE;
4878 (define_expand "mov<mode>cc"
4879    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4880          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4881                            (match_operand:GPR 2 "gpc_reg_operand" "")
4882                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4883   "TARGET_ISEL<sel>"
4884   "
4886   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4887     DONE;
4888   else
4889     FAIL;
4892 ;; We use the BASE_REGS for the isel input operands because, if rA is
4893 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4894 ;; because we may switch the operands and rB may end up being rA.
4896 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4897 ;; leave out the mode in operand 4 and use one pattern, but reload can
4898 ;; change the mode underneath our feet and then gets confused trying
4899 ;; to reload the value.
4900 (define_insn "isel_signed_<mode>"
4901   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4902         (if_then_else:GPR
4903          (match_operator 1 "scc_comparison_operator"
4904                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4905                           (const_int 0)])
4906          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4907          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4908   "TARGET_ISEL<sel>"
4909   "*
4910 { return output_isel (operands); }"
4911   [(set_attr "type" "isel")
4912    (set_attr "length" "4")])
4914 (define_insn "isel_unsigned_<mode>"
4915   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4916         (if_then_else:GPR
4917          (match_operator 1 "scc_comparison_operator"
4918                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4919                           (const_int 0)])
4920          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4921          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4922   "TARGET_ISEL<sel>"
4923   "*
4924 { return output_isel (operands); }"
4925   [(set_attr "type" "isel")
4926    (set_attr "length" "4")])
4928 ;; These patterns can be useful for combine; they let combine know that
4929 ;; isel can handle reversed comparisons so long as the operands are
4930 ;; registers.
4932 (define_insn "*isel_reversed_signed_<mode>"
4933   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4934         (if_then_else:GPR
4935          (match_operator 1 "scc_rev_comparison_operator"
4936                          [(match_operand:CC 4 "cc_reg_operand" "y")
4937                           (const_int 0)])
4938          (match_operand:GPR 2 "gpc_reg_operand" "b")
4939          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4940   "TARGET_ISEL<sel>"
4941   "*
4942 { return output_isel (operands); }"
4943   [(set_attr "type" "isel")
4944    (set_attr "length" "4")])
4946 (define_insn "*isel_reversed_unsigned_<mode>"
4947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4948         (if_then_else:GPR
4949          (match_operator 1 "scc_rev_comparison_operator"
4950                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4951                           (const_int 0)])
4952          (match_operand:GPR 2 "gpc_reg_operand" "b")
4953          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4954   "TARGET_ISEL<sel>"
4955   "*
4956 { return output_isel (operands); }"
4957   [(set_attr "type" "isel")
4958    (set_attr "length" "4")])
4960 ;; Floating point conditional move
4961 (define_expand "mov<mode>cc"
4962    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4963          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4964                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4965                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4966   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4967   "
4969   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4970     DONE;
4971   else
4972     FAIL;
4975 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4976   [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4977         (if_then_else:SFDF
4978          (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4979              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4980          (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4981          (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4982   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4983   "fsel %0,%1,%2,%3"
4984   [(set_attr "type" "fp")])
4986 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4987   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4988         (if_then_else:SFDF
4989          (match_operator:CCFP 1 "fpmask_comparison_operator"
4990                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4991                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4992          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4993          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4994    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4995   "TARGET_P9_MINMAX"
4996   "#"
4997   ""
4998   [(set (match_dup 6)
4999         (if_then_else:V2DI (match_dup 1)
5000                            (match_dup 7)
5001                            (match_dup 8)))
5002    (set (match_dup 0)
5003         (if_then_else:SFDF (ne (match_dup 6)
5004                                (match_dup 8))
5005                            (match_dup 4)
5006                            (match_dup 5)))]
5008   if (GET_CODE (operands[6]) == SCRATCH)
5009     operands[6] = gen_reg_rtx (V2DImode);
5011   operands[7] = CONSTM1_RTX (V2DImode);
5012   operands[8] = CONST0_RTX (V2DImode);
5014  [(set_attr "length" "8")
5015   (set_attr "type" "vecperm")])
5017 ;; Handle inverting the fpmask comparisons.
5018 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5019   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5020         (if_then_else:SFDF
5021          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5022                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5023                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5024          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5025          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5026    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5027   "TARGET_P9_MINMAX"
5028   "#"
5029   "&& 1"
5030   [(set (match_dup 6)
5031         (if_then_else:V2DI (match_dup 9)
5032                            (match_dup 7)
5033                            (match_dup 8)))
5034    (set (match_dup 0)
5035         (if_then_else:SFDF (ne (match_dup 6)
5036                                (match_dup 8))
5037                            (match_dup 5)
5038                            (match_dup 4)))]
5040   rtx op1 = operands[1];
5041   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5043   if (GET_CODE (operands[6]) == SCRATCH)
5044     operands[6] = gen_reg_rtx (V2DImode);
5046   operands[7] = CONSTM1_RTX (V2DImode);
5047   operands[8] = CONST0_RTX (V2DImode);
5049   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5051  [(set_attr "length" "8")
5052   (set_attr "type" "vecperm")])
5054 (define_insn "*fpmask<mode>"
5055   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5056         (if_then_else:V2DI
5057          (match_operator:CCFP 1 "fpmask_comparison_operator"
5058                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5059                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5060          (match_operand:V2DI 4 "all_ones_constant" "")
5061          (match_operand:V2DI 5 "zero_constant" "")))]
5062   "TARGET_P9_MINMAX"
5063   "xscmp%V1dp %x0,%x2,%x3"
5064   [(set_attr "type" "fpcompare")])
5066 (define_insn "*xxsel<mode>"
5067   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5068         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5069                                (match_operand:V2DI 2 "zero_constant" ""))
5070                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5071                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5072   "TARGET_P9_MINMAX"
5073   "xxsel %x0,%x4,%x3,%x1"
5074   [(set_attr "type" "vecmove")])
5077 ;; Conversions to and from floating-point.
5079 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5080 ; don't want to support putting SImode in FPR registers.
5081 (define_insn "lfiwax"
5082   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5083         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5084                    UNSPEC_LFIWAX))]
5085   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5086   "@
5087    lfiwax %0,%y1
5088    lxsiwax %x0,%y1
5089    mtvsrwa %x0,%1
5090    vextsw2d %0,%1"
5091   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5093 ; This split must be run before register allocation because it allocates the
5094 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5095 ; it earlier to allow for the combiner to merge insns together where it might
5096 ; not be needed and also in case the insns are deleted as dead code.
5098 (define_insn_and_split "floatsi<mode>2_lfiwax"
5099   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5100         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5101    (clobber (match_scratch:DI 2 "=wi"))]
5102   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5103    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5104   "#"
5105   ""
5106   [(pc)]
5107   "
5109   rtx dest = operands[0];
5110   rtx src = operands[1];
5111   rtx tmp;
5113   if (!MEM_P (src) && TARGET_POWERPC64
5114       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5115     tmp = convert_to_mode (DImode, src, false);
5116   else
5117     {
5118       tmp = operands[2];
5119       if (GET_CODE (tmp) == SCRATCH)
5120         tmp = gen_reg_rtx (DImode);
5121       if (MEM_P (src))
5122         {
5123           src = rs6000_address_for_fpconvert (src);
5124           emit_insn (gen_lfiwax (tmp, src));
5125         }
5126       else
5127         {
5128           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5129           emit_move_insn (stack, src);
5130           emit_insn (gen_lfiwax (tmp, stack));
5131         }
5132     }
5133   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5134   DONE;
5136   [(set_attr "length" "12")
5137    (set_attr "type" "fpload")])
5139 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5140   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5141         (float:SFDF
5142          (sign_extend:DI
5143           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5144    (clobber (match_scratch:DI 2 "=wi"))]
5145   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5146    && <SI_CONVERT_FP>"
5147   "#"
5148   ""
5149   [(pc)]
5150   "
5152   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5153   if (GET_CODE (operands[2]) == SCRATCH)
5154     operands[2] = gen_reg_rtx (DImode);
5155   if (TARGET_VSX_SMALL_INTEGER)
5156     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5157   else
5158     emit_insn (gen_lfiwax (operands[2], operands[1]));
5159   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5160   DONE;
5162   [(set_attr "length" "8")
5163    (set_attr "type" "fpload")])
5165 (define_insn "lfiwzx"
5166   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5167         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5168                    UNSPEC_LFIWZX))]
5169   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5170   "@
5171    lfiwzx %0,%y1
5172    lxsiwzx %x0,%y1
5173    mtvsrwz %x0,%1
5174    xxextractuw %x0,%x1,4"
5175   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5177 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5178   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5179         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5180    (clobber (match_scratch:DI 2 "=wi"))]
5181   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5182    && <SI_CONVERT_FP>"
5183   "#"
5184   ""
5185   [(pc)]
5186   "
5188   rtx dest = operands[0];
5189   rtx src = operands[1];
5190   rtx tmp;
5192   if (!MEM_P (src) && TARGET_POWERPC64
5193       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5194     tmp = convert_to_mode (DImode, src, true);
5195   else
5196     {
5197       tmp = operands[2];
5198       if (GET_CODE (tmp) == SCRATCH)
5199         tmp = gen_reg_rtx (DImode);
5200       if (MEM_P (src))
5201         {
5202           src = rs6000_address_for_fpconvert (src);
5203           emit_insn (gen_lfiwzx (tmp, src));
5204         }
5205       else
5206         {
5207           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5208           emit_move_insn (stack, src);
5209           emit_insn (gen_lfiwzx (tmp, stack));
5210         }
5211     }
5212   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5213   DONE;
5215   [(set_attr "length" "12")
5216    (set_attr "type" "fpload")])
5218 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5219   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5220         (unsigned_float:SFDF
5221          (zero_extend:DI
5222           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5223    (clobber (match_scratch:DI 2 "=wi"))]
5224   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5225    && <SI_CONVERT_FP>"
5226   "#"
5227   ""
5228   [(pc)]
5229   "
5231   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5232   if (GET_CODE (operands[2]) == SCRATCH)
5233     operands[2] = gen_reg_rtx (DImode);
5234   if (TARGET_VSX_SMALL_INTEGER)
5235     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5236   else
5237     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5238   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5239   DONE;
5241   [(set_attr "length" "8")
5242    (set_attr "type" "fpload")])
5244 ; For each of these conversions, there is a define_expand, a define_insn
5245 ; with a '#' template, and a define_split (with C code).  The idea is
5246 ; to allow constant folding with the template of the define_insn,
5247 ; then to have the insns split later (between sched1 and final).
5249 (define_expand "floatsidf2"
5250   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5251                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5252               (use (match_dup 2))
5253               (use (match_dup 3))
5254               (clobber (match_dup 4))
5255               (clobber (match_dup 5))
5256               (clobber (match_dup 6))])]
5257   "TARGET_HARD_FLOAT 
5258    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5259   "
5261   if (TARGET_E500_DOUBLE)
5262     {
5263       if (!REG_P (operands[1]))
5264         operands[1] = force_reg (SImode, operands[1]);
5265       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5266       DONE;
5267     }
5268   else if (TARGET_LFIWAX && TARGET_FCFID)
5269     {
5270       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5271       DONE;
5272     }
5273   else if (TARGET_FCFID)
5274     {
5275       rtx dreg = operands[1];
5276       if (!REG_P (dreg))
5277         dreg = force_reg (SImode, dreg);
5278       dreg = convert_to_mode (DImode, dreg, false);
5279       emit_insn (gen_floatdidf2 (operands[0], dreg));
5280       DONE;
5281     }
5283   if (!REG_P (operands[1]))
5284     operands[1] = force_reg (SImode, operands[1]);
5285   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5286   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5287   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5288   operands[5] = gen_reg_rtx (DFmode);
5289   operands[6] = gen_reg_rtx (SImode);
5292 (define_insn_and_split "*floatsidf2_internal"
5293   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5294         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5295    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5296    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5297    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5298    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5299    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5300   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5301   "#"
5302   ""
5303   [(pc)]
5304   "
5306   rtx lowword, highword;
5307   gcc_assert (MEM_P (operands[4]));
5308   highword = adjust_address (operands[4], SImode, 0);
5309   lowword = adjust_address (operands[4], SImode, 4);
5310   if (! WORDS_BIG_ENDIAN)
5311     std::swap (lowword, highword);
5313   emit_insn (gen_xorsi3 (operands[6], operands[1],
5314                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5315   emit_move_insn (lowword, operands[6]);
5316   emit_move_insn (highword, operands[2]);
5317   emit_move_insn (operands[5], operands[4]);
5318   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5319   DONE;
5321   [(set_attr "length" "24")
5322    (set_attr "type" "fp")])
5324 ;; If we don't have a direct conversion to single precision, don't enable this
5325 ;; conversion for 32-bit without fast math, because we don't have the insn to
5326 ;; generate the fixup swizzle to avoid double rounding problems.
5327 (define_expand "floatunssisf2"
5328   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5329         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5330   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5331    && (!TARGET_FPRS
5332        || (TARGET_FPRS
5333            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5334                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5335                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5336   "
5338   if (!TARGET_FPRS)
5339     {
5340       if (!REG_P (operands[1]))
5341         operands[1] = force_reg (SImode, operands[1]);
5342     }
5343   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5344     {
5345       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5346       DONE;
5347     }
5348   else
5349     {
5350       rtx dreg = operands[1];
5351       if (!REG_P (dreg))
5352         dreg = force_reg (SImode, dreg);
5353       dreg = convert_to_mode (DImode, dreg, true);
5354       emit_insn (gen_floatdisf2 (operands[0], dreg));
5355       DONE;
5356     }
5359 (define_expand "floatunssidf2"
5360   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5361                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5362               (use (match_dup 2))
5363               (use (match_dup 3))
5364               (clobber (match_dup 4))
5365               (clobber (match_dup 5))])]
5366   "TARGET_HARD_FLOAT
5367    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5368   "
5370   if (TARGET_E500_DOUBLE)
5371     {
5372       if (!REG_P (operands[1]))
5373         operands[1] = force_reg (SImode, operands[1]);
5374       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5375       DONE;
5376     }
5377   else if (TARGET_LFIWZX && TARGET_FCFID)
5378     {
5379       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5380       DONE;
5381     }
5382   else if (TARGET_FCFID)
5383     {
5384       rtx dreg = operands[1];
5385       if (!REG_P (dreg))
5386         dreg = force_reg (SImode, dreg);
5387       dreg = convert_to_mode (DImode, dreg, true);
5388       emit_insn (gen_floatdidf2 (operands[0], dreg));
5389       DONE;
5390     }
5392   if (!REG_P (operands[1]))
5393     operands[1] = force_reg (SImode, operands[1]);
5394   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5395   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5396   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5397   operands[5] = gen_reg_rtx (DFmode);
5400 (define_insn_and_split "*floatunssidf2_internal"
5401   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5402         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5403    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5404    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5405    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5406    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5407   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5408    && !(TARGET_FCFID && TARGET_POWERPC64)"
5409   "#"
5410   ""
5411   [(pc)]
5412   "
5414   rtx lowword, highword;
5415   gcc_assert (MEM_P (operands[4]));
5416   highword = adjust_address (operands[4], SImode, 0);
5417   lowword = adjust_address (operands[4], SImode, 4);
5418   if (! WORDS_BIG_ENDIAN)
5419     std::swap (lowword, highword);
5421   emit_move_insn (lowword, operands[1]);
5422   emit_move_insn (highword, operands[2]);
5423   emit_move_insn (operands[5], operands[4]);
5424   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5425   DONE;
5427   [(set_attr "length" "20")
5428    (set_attr "type" "fp")])
5430 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5431 ;; vector registers.  These insns favor doing the sign/zero extension in
5432 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5433 ;; extension and then a direct move.
5435 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5436   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5437                    (float:FP_ISA3
5438                     (match_operand:QHI 1 "input_operand")))
5439               (clobber (match_scratch:DI 2))
5440               (clobber (match_scratch:DI 3))
5441               (clobber (match_scratch:<QHI:MODE> 4))])]
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 "*float<QHI:mode><FP_ISA3:mode>2_internal"
5450   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5451         (float:FP_ISA3
5452          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5453    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5454    (clobber (match_scratch:DI 3 "=X,r,X"))
5455    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5456   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5457    && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5458   "#"
5459   "&& reload_completed"
5460   [(const_int 0)]
5462   rtx result = operands[0];
5463   rtx input = operands[1];
5464   rtx di = operands[2];
5466   if (!MEM_P (input))
5467     {
5468       rtx tmp = operands[3];
5469       if (altivec_register_operand (input, <QHI:MODE>mode))
5470         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5471       else if (GET_CODE (tmp) == SCRATCH)
5472         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5473       else
5474         {
5475           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5476           emit_move_insn (di, tmp);
5477         }
5478     }
5479   else
5480     {
5481       rtx tmp = operands[4];
5482       emit_move_insn (tmp, input);
5483       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5484     }
5486   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5487   DONE;
5490 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5491   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5492                    (unsigned_float:FP_ISA3
5493                     (match_operand:QHI 1 "input_operand" "")))
5494               (clobber (match_scratch:DI 2 ""))
5495               (clobber (match_scratch:DI 3 ""))])]
5496   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5497    && TARGET_VSX_SMALL_INTEGER"
5499   if (MEM_P (operands[1]))
5500     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5503 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5504   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5505         (unsigned_float:FP_ISA3
5506          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5507    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5508    (clobber (match_scratch:DI 3 "=X,r,X"))]
5509   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5510    && TARGET_VSX_SMALL_INTEGER"
5511   "#"
5512   "&& reload_completed"
5513   [(const_int 0)]
5515   rtx result = operands[0];
5516   rtx input = operands[1];
5517   rtx di = operands[2];
5519   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5520     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5521   else
5522     {
5523       rtx tmp = operands[3];
5524       if (GET_CODE (tmp) == SCRATCH)
5525         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5526       else
5527         {
5528           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5529           emit_move_insn (di, tmp);
5530         }
5531     }
5533   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5534   DONE;
5537 (define_expand "fix_trunc<mode>si2"
5538   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5539         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5540   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5541   "
5543   if (!<E500_CONVERT>)
5544     {
5545       rtx src = force_reg (<MODE>mode, operands[1]);
5547       if (TARGET_STFIWX)
5548         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5549       else
5550         {
5551           rtx tmp = gen_reg_rtx (DImode);
5552           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5553           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5554                                                       tmp, stack));
5555         }
5556       DONE;
5557     }
5560 ; Like the convert to float patterns, this insn must be split before
5561 ; register allocation so that it can allocate the memory slot if it
5562 ; needed
5563 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5564   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5565         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5566    (clobber (match_scratch:DI 2 "=d"))]
5567   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5568    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5569    && TARGET_STFIWX && can_create_pseudo_p ()"
5570   "#"
5571   ""
5572   [(pc)]
5574   rtx dest = operands[0];
5575   rtx src = operands[1];
5576   rtx tmp = operands[2];
5578   if (GET_CODE (tmp) == SCRATCH)
5579     tmp = gen_reg_rtx (DImode);
5581   emit_insn (gen_fctiwz_<mode> (tmp, src));
5582   if (MEM_P (dest))
5583     {
5584       dest = rs6000_address_for_fpconvert (dest);
5585       emit_insn (gen_stfiwx (dest, tmp));
5586       DONE;
5587     }
5588   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5589     {
5590       dest = gen_lowpart (DImode, dest);
5591       emit_move_insn (dest, tmp);
5592       DONE;
5593     }
5594   else
5595     {
5596       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5597       emit_insn (gen_stfiwx (stack, tmp));
5598       emit_move_insn (dest, stack);
5599       DONE;
5600     }
5602   [(set_attr "length" "12")
5603    (set_attr "type" "fp")])
5605 (define_insn_and_split "fix_trunc<mode>si2_internal"
5606   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5607         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5608    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5609    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5610   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5611   "#"
5612   ""
5613   [(pc)]
5614   "
5616   rtx lowword;
5617   gcc_assert (MEM_P (operands[3]));
5618   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5620   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5621   emit_move_insn (operands[3], operands[2]);
5622   emit_move_insn (operands[0], lowword);
5623   DONE;
5625   [(set_attr "length" "16")
5626    (set_attr "type" "fp")])
5628 (define_expand "fix_trunc<mode>di2"
5629   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5630         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5631   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5632    && TARGET_FCFID"
5633   "")
5635 (define_insn "*fix_trunc<mode>di2_fctidz"
5636   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5637         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5638   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5639     && TARGET_FCFID"
5640   "@
5641    fctidz %0,%1
5642    xscvdpsxds %x0,%x1"
5643   [(set_attr "type" "fp")])
5645 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5646   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5647                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5648               (clobber (match_scratch:DI 2))])]
5649   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5650    && TARGET_VSX_SMALL_INTEGER"
5652   if (MEM_P (operands[0]))
5653     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5656 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5657   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5658         (fix:QHI
5659          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5660    (clobber (match_scratch:DI 2 "=X,wi"))]
5661   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5662    && TARGET_VSX_SMALL_INTEGER"
5663   "#"
5664   "&& reload_completed"
5665   [(const_int 0)]
5667   rtx dest = operands[0];
5668   rtx src = operands[1];
5670   if (vsx_register_operand (dest, <QHI:MODE>mode))
5671     {
5672       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5673       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5674     }
5675   else
5676     {
5677       rtx tmp = operands[2];
5678       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5680       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5681       emit_move_insn (dest, tmp2);
5682     }
5683   DONE;
5686 (define_expand "fixuns_trunc<mode>si2"
5687   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5688         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5689   "TARGET_HARD_FLOAT
5690    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5691        || <E500_CONVERT>)"
5692   "
5694   if (!<E500_CONVERT>)
5695     {
5696       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5697       DONE;
5698     }
5701 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5702   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5703         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5704    (clobber (match_scratch:DI 2 "=d"))]
5705   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5706    && TARGET_STFIWX && can_create_pseudo_p ()"
5707   "#"
5708   ""
5709   [(pc)]
5711   rtx dest = operands[0];
5712   rtx src = operands[1];
5713   rtx tmp = operands[2];
5715   if (GET_CODE (tmp) == SCRATCH)
5716     tmp = gen_reg_rtx (DImode);
5718   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5719   if (MEM_P (dest))
5720     {
5721       dest = rs6000_address_for_fpconvert (dest);
5722       emit_insn (gen_stfiwx (dest, tmp));
5723       DONE;
5724     }
5725   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5726     {
5727       dest = gen_lowpart (DImode, dest);
5728       emit_move_insn (dest, tmp);
5729       DONE;
5730     }
5731   else
5732     {
5733       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5734       emit_insn (gen_stfiwx (stack, tmp));
5735       emit_move_insn (dest, stack);
5736       DONE;
5737     }
5739   [(set_attr "length" "12")
5740    (set_attr "type" "fp")])
5742 (define_insn "fixuns_trunc<mode>di2"
5743   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5744         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5745   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5746   "@
5747    fctiduz %0,%1
5748    xscvdpuxds %x0,%x1"
5749   [(set_attr "type" "fp")])
5751 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5752   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5753                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5754               (clobber (match_scratch:DI 2))])]
5755   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5756    && TARGET_VSX_SMALL_INTEGER"
5758   if (MEM_P (operands[0]))
5759     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5762 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5763   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5764         (unsigned_fix:QHI
5765          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5766    (clobber (match_scratch:DI 2 "=X,wi"))]
5767   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5768    && TARGET_VSX_SMALL_INTEGER"
5769   "#"
5770   "&& reload_completed"
5771   [(const_int 0)]
5773   rtx dest = operands[0];
5774   rtx src = operands[1];
5776   if (vsx_register_operand (dest, <QHI:MODE>mode))
5777     {
5778       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5779       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5780     }
5781   else
5782     {
5783       rtx tmp = operands[2];
5784       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5786       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5787       emit_move_insn (dest, tmp2);
5788     }
5789   DONE;
5791 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5792 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5793 ; because the first makes it clear that operand 0 is not live
5794 ; before the instruction.
5795 (define_insn "fctiwz_<mode>"
5796   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5797         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5798                    UNSPEC_FCTIWZ))]
5799   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5800   "@
5801    fctiwz %0,%1
5802    xscvdpsxws %x0,%x1"
5803   [(set_attr "type" "fp")])
5805 (define_insn "fctiwuz_<mode>"
5806   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5807         (unspec:DI [(unsigned_fix:SI
5808                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5809                    UNSPEC_FCTIWUZ))]
5810   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5811   "@
5812    fctiwuz %0,%1
5813    xscvdpuxws %x0,%x1"
5814   [(set_attr "type" "fp")])
5816 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5817 ;; since the friz instruction does not truncate the value if the floating
5818 ;; point value is < LONG_MIN or > LONG_MAX.
5819 (define_insn "*friz"
5820   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5821         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5822   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5823    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5824   "@
5825    friz %0,%1
5826    xsrdpiz %x0,%x1"
5827   [(set_attr "type" "fp")])
5829 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5830 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5831 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5832 ;; extend it, store it back on the stack from the GPR, load it back into the
5833 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5834 ;; disable using store and load to sign/zero extend the value.
5835 (define_insn_and_split "*round32<mode>2_fprs"
5836   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5837         (float:SFDF
5838          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5839    (clobber (match_scratch:DI 2 "=d"))
5840    (clobber (match_scratch:DI 3 "=d"))]
5841   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5842    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5843    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5844   "#"
5845   ""
5846   [(pc)]
5848   rtx dest = operands[0];
5849   rtx src = operands[1];
5850   rtx tmp1 = operands[2];
5851   rtx tmp2 = operands[3];
5852   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5854   if (GET_CODE (tmp1) == SCRATCH)
5855     tmp1 = gen_reg_rtx (DImode);
5856   if (GET_CODE (tmp2) == SCRATCH)
5857     tmp2 = gen_reg_rtx (DImode);
5859   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5860   emit_insn (gen_stfiwx (stack, tmp1));
5861   emit_insn (gen_lfiwax (tmp2, stack));
5862   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5863   DONE;
5865   [(set_attr "type" "fpload")
5866    (set_attr "length" "16")])
5868 (define_insn_and_split "*roundu32<mode>2_fprs"
5869   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5870         (unsigned_float:SFDF
5871          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5872    (clobber (match_scratch:DI 2 "=d"))
5873    (clobber (match_scratch:DI 3 "=d"))]
5874   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5875    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5876    && can_create_pseudo_p ()"
5877   "#"
5878   ""
5879   [(pc)]
5881   rtx dest = operands[0];
5882   rtx src = operands[1];
5883   rtx tmp1 = operands[2];
5884   rtx tmp2 = operands[3];
5885   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5887   if (GET_CODE (tmp1) == SCRATCH)
5888     tmp1 = gen_reg_rtx (DImode);
5889   if (GET_CODE (tmp2) == SCRATCH)
5890     tmp2 = gen_reg_rtx (DImode);
5892   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5893   emit_insn (gen_stfiwx (stack, tmp1));
5894   emit_insn (gen_lfiwzx (tmp2, stack));
5895   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5896   DONE;
5898   [(set_attr "type" "fpload")
5899    (set_attr "length" "16")])
5901 ;; No VSX equivalent to fctid
5902 (define_insn "lrint<mode>di2"
5903   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5904         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5905                    UNSPEC_FCTID))]
5906   "TARGET_<MODE>_FPR && TARGET_FPRND"
5907   "fctid %0,%1"
5908   [(set_attr "type" "fp")])
5910 (define_insn "btrunc<mode>2"
5911   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5912         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5913                      UNSPEC_FRIZ))]
5914   "TARGET_<MODE>_FPR && TARGET_FPRND"
5915   "@
5916    friz %0,%1
5917    xsrdpiz %x0,%x1"
5918   [(set_attr "type" "fp")
5919    (set_attr "fp_type" "fp_addsub_<Fs>")])
5921 (define_insn "ceil<mode>2"
5922   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5923         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5924                      UNSPEC_FRIP))]
5925   "TARGET_<MODE>_FPR && TARGET_FPRND"
5926   "@
5927    frip %0,%1
5928    xsrdpip %x0,%x1"
5929   [(set_attr "type" "fp")
5930    (set_attr "fp_type" "fp_addsub_<Fs>")])
5932 (define_insn "floor<mode>2"
5933   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5934         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5935                      UNSPEC_FRIM))]
5936   "TARGET_<MODE>_FPR && TARGET_FPRND"
5937   "@
5938    frim %0,%1
5939    xsrdpim %x0,%x1"
5940   [(set_attr "type" "fp")
5941    (set_attr "fp_type" "fp_addsub_<Fs>")])
5943 ;; No VSX equivalent to frin
5944 (define_insn "round<mode>2"
5945   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5946         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5947                      UNSPEC_FRIN))]
5948   "TARGET_<MODE>_FPR && TARGET_FPRND"
5949   "frin %0,%1"
5950   [(set_attr "type" "fp")
5951    (set_attr "fp_type" "fp_addsub_<Fs>")])
5953 (define_insn "*xsrdpi<mode>2"
5954   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5955         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5956                      UNSPEC_XSRDPI))]
5957   "TARGET_<MODE>_FPR && TARGET_VSX"
5958   "xsrdpi %x0,%x1"
5959   [(set_attr "type" "fp")
5960    (set_attr "fp_type" "fp_addsub_<Fs>")])
5962 (define_expand "lround<mode>di2"
5963   [(set (match_dup 2)
5964         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5965                      UNSPEC_XSRDPI))
5966    (set (match_operand:DI 0 "gpc_reg_operand" "")
5967         (unspec:DI [(match_dup 2)]
5968                    UNSPEC_FCTID))]
5969   "TARGET_<MODE>_FPR && TARGET_VSX"
5971   operands[2] = gen_reg_rtx (<MODE>mode);
5974 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5975 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5976 ; is only generated for Power8 or later.
5977 (define_insn "stfiwx"
5978   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5979         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5980                    UNSPEC_STFIWX))]
5981   "TARGET_PPC_GFXOPT"
5982   "@
5983    stfiwx %1,%y0
5984    stxsiwx %x1,%y0"
5985   [(set_attr "type" "fpstore")])
5987 ;; If we don't have a direct conversion to single precision, don't enable this
5988 ;; conversion for 32-bit without fast math, because we don't have the insn to
5989 ;; generate the fixup swizzle to avoid double rounding problems.
5990 (define_expand "floatsisf2"
5991   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5992         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5993   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5994    && (!TARGET_FPRS
5995        || (TARGET_FPRS
5996            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5997                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5998                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5999   "
6001   if (!TARGET_FPRS)
6002     {
6003       if (!REG_P (operands[1]))
6004         operands[1] = force_reg (SImode, operands[1]);
6005     }
6006   else if (TARGET_FCFIDS && TARGET_LFIWAX)
6007     {
6008       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6009       DONE;
6010     }
6011   else if (TARGET_FCFID && TARGET_LFIWAX)
6012     {
6013       rtx dfreg = gen_reg_rtx (DFmode);
6014       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6015       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6016       DONE;
6017     }
6018   else
6019     {
6020       rtx dreg = operands[1];
6021       if (!REG_P (dreg))
6022         dreg = force_reg (SImode, dreg);
6023       dreg = convert_to_mode (DImode, dreg, false);
6024       emit_insn (gen_floatdisf2 (operands[0], dreg));
6025       DONE;
6026     }
6029 (define_expand "floatdidf2"
6030   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6031         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6032   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6033   "")
6035 (define_insn "*floatdidf2_fpr"
6036   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6037         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6038   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6039   "@
6040    fcfid %0,%1
6041    xscvsxddp %x0,%x1"
6042   [(set_attr "type" "fp")])
6044 ; Allow the combiner to merge source memory operands to the conversion so that
6045 ; the optimizer/register allocator doesn't try to load the value too early in a
6046 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6047 ; hit.  We will split after reload to avoid the trip through the GPRs
6049 (define_insn_and_split "*floatdidf2_mem"
6050   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6051         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6052    (clobber (match_scratch:DI 2 "=d,wi"))]
6053   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6054   "#"
6055   "&& reload_completed"
6056   [(set (match_dup 2) (match_dup 1))
6057    (set (match_dup 0) (float:DF (match_dup 2)))]
6058   ""
6059   [(set_attr "length" "8")
6060    (set_attr "type" "fpload")])
6062 (define_expand "floatunsdidf2"
6063   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6064         (unsigned_float:DF
6065          (match_operand:DI 1 "gpc_reg_operand" "")))]
6066   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6067   "")
6069 (define_insn "*floatunsdidf2_fcfidu"
6070   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6071         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6072   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6073   "@
6074    fcfidu %0,%1
6075    xscvuxddp %x0,%x1"
6076   [(set_attr "type" "fp")
6077    (set_attr "length" "4")])
6079 (define_insn_and_split "*floatunsdidf2_mem"
6080   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6081         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6082    (clobber (match_scratch:DI 2 "=d,wi"))]
6083   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6084   "#"
6085   "&& reload_completed"
6086   [(set (match_dup 2) (match_dup 1))
6087    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6088   ""
6089   [(set_attr "length" "8")
6090    (set_attr "type" "fpload")])
6092 (define_expand "floatdisf2"
6093   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6094         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6095   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6096    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6097   "
6099   if (!TARGET_FCFIDS)
6100     {
6101       rtx val = operands[1];
6102       if (!flag_unsafe_math_optimizations)
6103         {
6104           rtx label = gen_label_rtx ();
6105           val = gen_reg_rtx (DImode);
6106           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6107           emit_label (label);
6108         }
6109       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6110       DONE;
6111     }
6114 (define_insn "floatdisf2_fcfids"
6115   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6116         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6117   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6118    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6119   "@
6120    fcfids %0,%1
6121    xscvsxdsp %x0,%x1"
6122   [(set_attr "type" "fp")])
6124 (define_insn_and_split "*floatdisf2_mem"
6125   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6126         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6127    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6128   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6129    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6130   "#"
6131   "&& reload_completed"
6132   [(pc)]
6133   "
6135   emit_move_insn (operands[2], operands[1]);
6136   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6137   DONE;
6139   [(set_attr "length" "8")])
6141 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6142 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6143 ;; from double rounding.
6144 ;; Instead of creating a new cpu type for two FP operations, just use fp
6145 (define_insn_and_split "floatdisf2_internal1"
6146   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6147         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6148    (clobber (match_scratch:DF 2 "=d"))]
6149   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6150    && !TARGET_FCFIDS"
6151   "#"
6152   "&& reload_completed"
6153   [(set (match_dup 2)
6154         (float:DF (match_dup 1)))
6155    (set (match_dup 0)
6156         (float_truncate:SF (match_dup 2)))]
6157   ""
6158   [(set_attr "length" "8")
6159    (set_attr "type" "fp")])
6161 ;; Twiddles bits to avoid double rounding.
6162 ;; Bits that might be truncated when converting to DFmode are replaced
6163 ;; by a bit that won't be lost at that stage, but is below the SFmode
6164 ;; rounding position.
6165 (define_expand "floatdisf2_internal2"
6166   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6167                                               (const_int 53)))
6168               (clobber (reg:DI CA_REGNO))])
6169    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6170                                            (const_int 2047)))
6171    (set (match_dup 3) (plus:DI (match_dup 3)
6172                                (const_int 1)))
6173    (set (match_dup 0) (plus:DI (match_dup 0)
6174                                (const_int 2047)))
6175    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6176                                      (const_int 2)))
6177    (set (match_dup 0) (ior:DI (match_dup 0)
6178                               (match_dup 1)))
6179    (set (match_dup 0) (and:DI (match_dup 0)
6180                               (const_int -2048)))
6181    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6182                            (label_ref (match_operand:DI 2 "" ""))
6183                            (pc)))
6184    (set (match_dup 0) (match_dup 1))]
6185   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6186    && !TARGET_FCFIDS"
6187   "
6189   operands[3] = gen_reg_rtx (DImode);
6190   operands[4] = gen_reg_rtx (CCUNSmode);
6193 (define_expand "floatunsdisf2"
6194   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6195         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6196   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6197    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6198   "")
6200 (define_insn "floatunsdisf2_fcfidus"
6201   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6202         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6203   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6204    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6205   "@
6206    fcfidus %0,%1
6207    xscvuxdsp %x0,%x1"
6208   [(set_attr "type" "fp")])
6210 (define_insn_and_split "*floatunsdisf2_mem"
6211   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6212         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6213    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6214   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6215    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6216   "#"
6217   "&& reload_completed"
6218   [(pc)]
6219   "
6221   emit_move_insn (operands[2], operands[1]);
6222   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6223   DONE;
6225   [(set_attr "length" "8")
6226    (set_attr "type" "fpload")])
6228 ;; Define the TImode operations that can be done in a small number
6229 ;; of instructions.  The & constraints are to prevent the register
6230 ;; allocator from allocating registers that overlap with the inputs
6231 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6232 ;; also allow for the output being the same as one of the inputs.
6234 (define_expand "addti3"
6235   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6236         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6237                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6238   "TARGET_64BIT"
6240   rtx lo0 = gen_lowpart (DImode, operands[0]);
6241   rtx lo1 = gen_lowpart (DImode, operands[1]);
6242   rtx lo2 = gen_lowpart (DImode, operands[2]);
6243   rtx hi0 = gen_highpart (DImode, operands[0]);
6244   rtx hi1 = gen_highpart (DImode, operands[1]);
6245   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6247   if (!reg_or_short_operand (lo2, DImode))
6248     lo2 = force_reg (DImode, lo2);
6249   if (!adde_operand (hi2, DImode))
6250     hi2 = force_reg (DImode, hi2);
6252   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6253   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6254   DONE;
6257 (define_expand "subti3"
6258   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6259         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6260                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6261   "TARGET_64BIT"
6263   rtx lo0 = gen_lowpart (DImode, operands[0]);
6264   rtx lo1 = gen_lowpart (DImode, operands[1]);
6265   rtx lo2 = gen_lowpart (DImode, operands[2]);
6266   rtx hi0 = gen_highpart (DImode, operands[0]);
6267   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6268   rtx hi2 = gen_highpart (DImode, operands[2]);
6270   if (!reg_or_short_operand (lo1, DImode))
6271     lo1 = force_reg (DImode, lo1);
6272   if (!adde_operand (hi1, DImode))
6273     hi1 = force_reg (DImode, hi1);
6275   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6276   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6277   DONE;
6280 ;; 128-bit logical operations expanders
6282 (define_expand "and<mode>3"
6283   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6284         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6285                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6286   ""
6287   "")
6289 (define_expand "ior<mode>3"
6290   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6291         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6292                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6293   ""
6294   "")
6296 (define_expand "xor<mode>3"
6297   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6298         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6299                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6300   ""
6301   "")
6303 (define_expand "one_cmpl<mode>2"
6304   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6305         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6306   ""
6307   "")
6309 (define_expand "nor<mode>3"
6310   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6311         (and:BOOL_128
6312          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6313          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6314   ""
6315   "")
6317 (define_expand "andc<mode>3"
6318   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6319         (and:BOOL_128
6320          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6321          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6322   ""
6323   "")
6325 ;; Power8 vector logical instructions.
6326 (define_expand "eqv<mode>3"
6327   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6328         (not:BOOL_128
6329          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6330                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6331   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6332   "")
6334 ;; Rewrite nand into canonical form
6335 (define_expand "nand<mode>3"
6336   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6337         (ior:BOOL_128
6338          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6339          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6340   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6341   "")
6343 ;; The canonical form is to have the negated element first, so we need to
6344 ;; reverse arguments.
6345 (define_expand "orc<mode>3"
6346   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6347         (ior:BOOL_128
6348          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6349          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6350   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6351   "")
6353 ;; 128-bit logical operations insns and split operations
6354 (define_insn_and_split "*and<mode>3_internal"
6355   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6356         (and:BOOL_128
6357          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6358          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6359   ""
6361   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6362     return "xxland %x0,%x1,%x2";
6364   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6365     return "vand %0,%1,%2";
6367   return "#";
6369   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6370   [(const_int 0)]
6372   rs6000_split_logical (operands, AND, false, false, false);
6373   DONE;
6375   [(set (attr "type")
6376       (if_then_else
6377         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6378         (const_string "veclogical")
6379         (const_string "integer")))
6380    (set (attr "length")
6381       (if_then_else
6382         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6383         (const_string "4")
6384         (if_then_else
6385          (match_test "TARGET_POWERPC64")
6386          (const_string "8")
6387          (const_string "16"))))])
6389 ;; 128-bit IOR/XOR
6390 (define_insn_and_split "*bool<mode>3_internal"
6391   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6392         (match_operator:BOOL_128 3 "boolean_or_operator"
6393          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6394           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6395   ""
6397   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6398     return "xxl%q3 %x0,%x1,%x2";
6400   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6401     return "v%q3 %0,%1,%2";
6403   return "#";
6405   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6406   [(const_int 0)]
6408   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6409   DONE;
6411   [(set (attr "type")
6412       (if_then_else
6413         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6414         (const_string "veclogical")
6415         (const_string "integer")))
6416    (set (attr "length")
6417       (if_then_else
6418         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6419         (const_string "4")
6420         (if_then_else
6421          (match_test "TARGET_POWERPC64")
6422          (const_string "8")
6423          (const_string "16"))))])
6425 ;; 128-bit ANDC/ORC
6426 (define_insn_and_split "*boolc<mode>3_internal1"
6427   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6428         (match_operator:BOOL_128 3 "boolean_operator"
6429          [(not:BOOL_128
6430            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6431           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6432   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6434   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6435     return "xxl%q3 %x0,%x1,%x2";
6437   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6438     return "v%q3 %0,%1,%2";
6440   return "#";
6442   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6443    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6444   [(const_int 0)]
6446   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6447   DONE;
6449   [(set (attr "type")
6450       (if_then_else
6451         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6452         (const_string "veclogical")
6453         (const_string "integer")))
6454    (set (attr "length")
6455       (if_then_else
6456         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6457         (const_string "4")
6458         (if_then_else
6459          (match_test "TARGET_POWERPC64")
6460          (const_string "8")
6461          (const_string "16"))))])
6463 (define_insn_and_split "*boolc<mode>3_internal2"
6464   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6465         (match_operator:TI2 3 "boolean_operator"
6466          [(not:TI2
6467            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6468           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6469   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6470   "#"
6471   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6472   [(const_int 0)]
6474   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6475   DONE;
6477   [(set_attr "type" "integer")
6478    (set (attr "length")
6479         (if_then_else
6480          (match_test "TARGET_POWERPC64")
6481          (const_string "8")
6482          (const_string "16")))])
6484 ;; 128-bit NAND/NOR
6485 (define_insn_and_split "*boolcc<mode>3_internal1"
6486   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6487         (match_operator:BOOL_128 3 "boolean_operator"
6488          [(not:BOOL_128
6489            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6490           (not:BOOL_128
6491            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6492   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6494   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6495     return "xxl%q3 %x0,%x1,%x2";
6497   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6498     return "v%q3 %0,%1,%2";
6500   return "#";
6502   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6503    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6504   [(const_int 0)]
6506   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6507   DONE;
6509   [(set (attr "type")
6510       (if_then_else
6511         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6512         (const_string "veclogical")
6513         (const_string "integer")))
6514    (set (attr "length")
6515       (if_then_else
6516         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6517         (const_string "4")
6518         (if_then_else
6519          (match_test "TARGET_POWERPC64")
6520          (const_string "8")
6521          (const_string "16"))))])
6523 (define_insn_and_split "*boolcc<mode>3_internal2"
6524   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6525         (match_operator:TI2 3 "boolean_operator"
6526          [(not:TI2
6527            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6528           (not:TI2
6529            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6530   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6531   "#"
6532   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6533   [(const_int 0)]
6535   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6536   DONE;
6538   [(set_attr "type" "integer")
6539    (set (attr "length")
6540         (if_then_else
6541          (match_test "TARGET_POWERPC64")
6542          (const_string "8")
6543          (const_string "16")))])
6546 ;; 128-bit EQV
6547 (define_insn_and_split "*eqv<mode>3_internal1"
6548   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6549         (not:BOOL_128
6550          (xor:BOOL_128
6551           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6552           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6553   "TARGET_P8_VECTOR"
6555   if (vsx_register_operand (operands[0], <MODE>mode))
6556     return "xxleqv %x0,%x1,%x2";
6558   return "#";
6560   "TARGET_P8_VECTOR && reload_completed
6561    && int_reg_operand (operands[0], <MODE>mode)"
6562   [(const_int 0)]
6564   rs6000_split_logical (operands, XOR, true, false, false);
6565   DONE;
6567   [(set (attr "type")
6568       (if_then_else
6569         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6570         (const_string "veclogical")
6571         (const_string "integer")))
6572    (set (attr "length")
6573       (if_then_else
6574         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6575         (const_string "4")
6576         (if_then_else
6577          (match_test "TARGET_POWERPC64")
6578          (const_string "8")
6579          (const_string "16"))))])
6581 (define_insn_and_split "*eqv<mode>3_internal2"
6582   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6583         (not:TI2
6584          (xor:TI2
6585           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6586           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6587   "!TARGET_P8_VECTOR"
6588   "#"
6589   "reload_completed && !TARGET_P8_VECTOR"
6590   [(const_int 0)]
6592   rs6000_split_logical (operands, XOR, true, false, false);
6593   DONE;
6595   [(set_attr "type" "integer")
6596    (set (attr "length")
6597         (if_then_else
6598          (match_test "TARGET_POWERPC64")
6599          (const_string "8")
6600          (const_string "16")))])
6602 ;; 128-bit one's complement
6603 (define_insn_and_split "*one_cmpl<mode>3_internal"
6604   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6605         (not:BOOL_128
6606           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6607   ""
6609   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6610     return "xxlnor %x0,%x1,%x1";
6612   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6613     return "vnor %0,%1,%1";
6615   return "#";
6617   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6618   [(const_int 0)]
6620   rs6000_split_logical (operands, NOT, false, false, false);
6621   DONE;
6623   [(set (attr "type")
6624       (if_then_else
6625         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6626         (const_string "veclogical")
6627         (const_string "integer")))
6628    (set (attr "length")
6629       (if_then_else
6630         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6631         (const_string "4")
6632         (if_then_else
6633          (match_test "TARGET_POWERPC64")
6634          (const_string "8")
6635          (const_string "16"))))])
6638 ;; Now define ways of moving data around.
6640 ;; Set up a register with a value from the GOT table
6642 (define_expand "movsi_got"
6643   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6644         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6645                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6646   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6647   "
6649   if (GET_CODE (operands[1]) == CONST)
6650     {
6651       rtx offset = const0_rtx;
6652       HOST_WIDE_INT value;
6654       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6655       value = INTVAL (offset);
6656       if (value != 0)
6657         {
6658           rtx tmp = (!can_create_pseudo_p ()
6659                      ? operands[0]
6660                      : gen_reg_rtx (Pmode));
6661           emit_insn (gen_movsi_got (tmp, operands[1]));
6662           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6663           DONE;
6664         }
6665     }
6667   operands[2] = rs6000_got_register (operands[1]);
6670 (define_insn "*movsi_got_internal"
6671   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6672         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6673                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6674                    UNSPEC_MOVSI_GOT))]
6675   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6676   "lwz %0,%a1@got(%2)"
6677   [(set_attr "type" "load")])
6679 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6680 ;; didn't get allocated to a hard register.
6681 (define_split
6682   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6683         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6684                     (match_operand:SI 2 "memory_operand" "")]
6685                    UNSPEC_MOVSI_GOT))]
6686   "DEFAULT_ABI == ABI_V4
6687     && flag_pic == 1
6688     && (reload_in_progress || reload_completed)"
6689   [(set (match_dup 0) (match_dup 2))
6690    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6691                                  UNSPEC_MOVSI_GOT))]
6692   "")
6694 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6695 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6696 ;; and this is even supposed to be faster, but it is simpler not to get
6697 ;; integers in the TOC.
6698 (define_insn "movsi_low"
6699   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6700         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6701                            (match_operand 2 "" ""))))]
6702   "TARGET_MACHO && ! TARGET_64BIT"
6703   "lwz %0,lo16(%2)(%1)"
6704   [(set_attr "type" "load")
6705    (set_attr "length" "4")])
6707 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6708 ;;              STW          STFIWX       STXSIWX      LI           LIS
6709 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6710 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6711 ;;              MF%1         MT%0         MT%0         NOP
6712 (define_insn "*movsi_internal1"
6713   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6714                 "=r,         r,           r,           ?*wI,        ?*wH,
6715                  m,          ?Z,          ?Z,          r,           r,
6716                  r,          ?*wIwH,      ?*wJwK,      ?*wK,        ?*wJwK,
6717                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6718                  r,          *c*l,        *h,          *h")
6720         (match_operand:SI 1 "input_operand"
6721                 "r,          U,           m,           Z,           Z,
6722                  r,          wI,          wH,          I,           L,
6723                  n,          wIwH,        O,           wM,          wB,
6724                  O,          wM,          wS,          r,           wIwH,
6725                  *h,         r,           r,           0"))]
6727   "!TARGET_SINGLE_FPU &&
6728    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6729   "@
6730    mr %0,%1
6731    la %0,%a1
6732    lwz%U1%X1 %0,%1
6733    lfiwzx %0,%y1
6734    lxsiwzx %x0,%y1
6735    stw%U0%X0 %1,%0
6736    stfiwx %1,%y0
6737    stxsiwx %x1,%y0
6738    li %0,%1
6739    lis %0,%v1
6740    #
6741    xxlor %x0,%x1,%x1
6742    xxspltib %x0,0
6743    xxspltib %x0,255
6744    vspltisw %0,%1
6745    xxlxor %x0,%x0,%x0
6746    xxlorc %x0,%x0,%x0
6747    #
6748    mtvsrwz %x0,%1
6749    mfvsrwz %0,%x1
6750    mf%1 %0
6751    mt%0 %1
6752    mt%0 %1
6753    nop"
6754   [(set_attr "type"
6755                 "*,          *,           load,        fpload,      fpload,
6756                  store,      fpstore,     fpstore,     *,           *,
6757                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6758                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6759                  *,           *,           *,           *")
6761    (set_attr "length"
6762                 "4,          4,           4,           4,           4,
6763                  4,          4,           4,           4,           4,
6764                  8,          4,           4,           4,           4,
6765                  4,          4,           8,           4,           4,
6766                  4,          4,           4,           4")])
6768 (define_insn "*movsi_internal1_single"
6769   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6770         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6771   "TARGET_SINGLE_FPU &&
6772    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6773   "@
6774    mr %0,%1
6775    la %0,%a1
6776    lwz%U1%X1 %0,%1
6777    stw%U0%X0 %1,%0
6778    li %0,%1
6779    lis %0,%v1
6780    #
6781    mf%1 %0
6782    mt%0 %1
6783    mt%0 %1
6784    nop
6785    stfs%U0%X0 %1,%0
6786    lfs%U1%X1 %0,%1"
6787   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6788    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6790 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6791 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6793 ;; Because SF values are actually stored as DF values within the vector
6794 ;; registers, we need to convert the value to the vector SF format when
6795 ;; we need to use the bits in a union or similar cases.  We only need
6796 ;; to do this transformation when the value is a vector register.  Loads,
6797 ;; stores, and transfers within GPRs are assumed to be safe.
6799 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6800 ;; no alternatives, because the call is created as part of secondary_reload,
6801 ;; and operand #2's register class is used to allocate the temporary register.
6802 ;; This function is called before reload, and it creates the temporary as
6803 ;; needed.
6805 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6806 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  MTVSRWZ
6807 ;;              VSX->VSX
6809 (define_insn_and_split "movsi_from_sf"
6810   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6811                 "=r,         r,           ?*wI,        ?*wH,     m,
6812                  m,          wY,          Z,           r,        wIwH,
6813                  ?wK")
6815         (unspec:SI [(match_operand:SF 1 "input_operand"
6816                 "r,          m,           Z,           Z,        r,
6817                  f,          wu,          wu,          wIwH,     r,
6818                  wK")]
6819                     UNSPEC_SI_FROM_SF))
6821    (clobber (match_scratch:V4SF 2
6822                 "=X,         X,           X,           X,        X,
6823                  X,          X,           X,           wa,       X,
6824                  wa"))]
6826   "TARGET_NO_SF_SUBREG
6827    && (register_operand (operands[0], SImode)
6828        || register_operand (operands[1], SFmode))"
6829   "@
6830    mr %0,%1
6831    lwz%U1%X1 %0,%1
6832    lfiwzx %0,%y1
6833    lxsiwzx %x0,%y1
6834    stw%U0%X0 %1,%0
6835    stfs%U0%X0 %1,%0
6836    stxssp %1,%0
6837    stxsspx %x1,%y0
6838    #
6839    mtvsrwz %x0,%1
6840    #"
6841   "&& reload_completed
6842    && register_operand (operands[0], SImode)
6843    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6844   [(const_int 0)]
6846   rtx op0 = operands[0];
6847   rtx op1 = operands[1];
6848   rtx op2 = operands[2];
6849   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6851   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6853   if (int_reg_operand (op0, SImode))
6854     {
6855       emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6856       emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6857     }
6858   else
6859     {
6860       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6861       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6862       emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6863     }
6865   DONE;
6867   [(set_attr "type"
6868                 "*,          load,        fpload,      fpload,   store,
6869                  fpstore,    fpstore,     fpstore,     mftgpr,   mffgpr,
6870                  veclogical")
6872    (set_attr "length"
6873                 "4,          4,           4,           4,        4,
6874                  4,          4,           4,           12,       4,
6875                  8")])
6877 ;; movsi_from_sf with zero extension
6879 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6880 ;;              MTVSRWZ      VSX->VSX
6882 (define_insn_and_split "*movdi_from_sf_zero_ext"
6883   [(set (match_operand:DI 0 "gpc_reg_operand"
6884                 "=r,         r,           ?*wI,        ?*wH,     r,
6885                 wIwH,        ?wK")
6887         (zero_extend:DI
6888          (unspec:SI [(match_operand:SF 1 "input_operand"
6889                 "r,          m,           Z,           Z,        wIwH,
6890                  r,          wK")]
6891                     UNSPEC_SI_FROM_SF)))
6893    (clobber (match_scratch:V4SF 2
6894                 "=X,         X,           X,           X,        wa,
6895                  X,          wa"))]
6897   "TARGET_DIRECT_MOVE_64BIT
6898    && (register_operand (operands[0], DImode)
6899        || register_operand (operands[1], SImode))"
6900   "@
6901    rldicl %0,%1,0,32
6902    lwz%U1%X1 %0,%1
6903    lfiwzx %0,%y1
6904    lxsiwzx %x0,%y1
6905    #
6906    mtvsrwz %x0,%1
6907    #"
6908   "&& reload_completed
6909    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6910   [(const_int 0)]
6912   rtx op0 = operands[0];
6913   rtx op1 = operands[1];
6914   rtx op2 = operands[2];
6916   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6918   if (int_reg_operand (op0, DImode))
6919     {
6920       emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6921       emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6922     }
6923   else
6924     {
6925       rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6926       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6927       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6928       emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6929     }
6931   DONE;
6933   [(set_attr "type"
6934                 "*,          load,        fpload,      fpload,  mftgpr,
6935                  mffgpr,     veclogical")
6937    (set_attr "length"
6938                 "4,          4,           4,           4,        12,
6939                  4,          8")])
6941 ;; Split a load of a large constant into the appropriate two-insn
6942 ;; sequence.
6944 (define_split
6945   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6946         (match_operand:SI 1 "const_int_operand" ""))]
6947   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6948    && (INTVAL (operands[1]) & 0xffff) != 0"
6949   [(set (match_dup 0)
6950         (match_dup 2))
6951    (set (match_dup 0)
6952         (ior:SI (match_dup 0)
6953                 (match_dup 3)))]
6954   "
6956   if (rs6000_emit_set_const (operands[0], operands[1]))
6957     DONE;
6958   else
6959     FAIL;
6962 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6963 (define_split
6964   [(set (match_operand:DI 0 "altivec_register_operand")
6965         (match_operand:DI 1 "xxspltib_constant_split"))]
6966   "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6967   [(const_int 0)]
6969   rtx op0 = operands[0];
6970   rtx op1 = operands[1];
6971   int r = REGNO (op0);
6972   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6974   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6975   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6976   DONE;
6979 (define_insn "*mov<mode>_internal2"
6980   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6981         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6982                     (const_int 0)))
6983    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6984   ""
6985   "@
6986    cmp<wd>i %2,%0,0
6987    mr. %0,%1
6988    #"
6989   [(set_attr "type" "cmp,logical,cmp")
6990    (set_attr "dot" "yes")
6991    (set_attr "length" "4,4,8")])
6993 (define_split
6994   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6995         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6996                     (const_int 0)))
6997    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6998   "reload_completed"
6999   [(set (match_dup 0) (match_dup 1))
7000    (set (match_dup 2)
7001         (compare:CC (match_dup 0)
7002                     (const_int 0)))]
7003   "")
7005 (define_expand "mov<mode>"
7006   [(set (match_operand:INT 0 "general_operand" "")
7007         (match_operand:INT 1 "any_operand" ""))]
7008   ""
7009   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7011 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7012 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7013 ;;              MTVSRWZ     MF%1       MT%1       NOP
7014 (define_insn "*mov<mode>_internal"
7015   [(set (match_operand:QHI 0 "nonimmediate_operand"
7016                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7017                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7018                  ?*wJwK,    r,         *c*l,      *h")
7020         (match_operand:QHI 1 "input_operand"
7021                 "r,         m,         Z,         r,         wJwK,      i,
7022                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7023                  r,         *h,        r,         0"))]
7025   "gpc_reg_operand (operands[0], <MODE>mode)
7026    || gpc_reg_operand (operands[1], <MODE>mode)"
7027   "@
7028    mr %0,%1
7029    l<wd>z%U1%X1 %0,%1
7030    lxsi<wd>zx %x0,%y1
7031    st<wd>%U0%X0 %1,%0
7032    stxsi<wd>x %x1,%y0
7033    li %0,%1
7034    xxlor %x0,%x1,%x1
7035    xxspltib %x0,0
7036    xxspltib %x0,255
7037    vspltis<wd> %0,%1
7038    #
7039    mfvsrwz %0,%x1
7040    mtvsrwz %x0,%1
7041    mf%1 %0
7042    mt%0 %1
7043    nop"
7044   [(set_attr "type"
7045                 "*,         load,      fpload,    store,     fpstore,   *,
7046                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7047                  mffgpr,    mfjmpr,    mtjmpr,    *")
7049    (set_attr "length"
7050                 "4,         4,         4,         4,         4,         4,
7051                  4,         4,         4,         4,         8,         4,
7052                  4,         4,         4,         4")])
7055 ;; Here is how to move condition codes around.  When we store CC data in
7056 ;; an integer register or memory, we store just the high-order 4 bits.
7057 ;; This lets us not shift in the most common case of CR0.
7058 (define_expand "movcc"
7059   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7060         (match_operand:CC 1 "nonimmediate_operand" ""))]
7061   ""
7062   "")
7064 (define_insn "*movcc_internal1"
7065   [(set (match_operand:CC 0 "nonimmediate_operand"
7066                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7067         (match_operand:CC 1 "general_operand"
7068                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7069   "register_operand (operands[0], CCmode)
7070    || register_operand (operands[1], CCmode)"
7071   "@
7072    mcrf %0,%1
7073    mtcrf 128,%1
7074    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7075    crxor %0,%0,%0
7076    mfcr %0%Q1
7077    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7078    mr %0,%1
7079    li %0,%1
7080    mf%1 %0
7081    mt%0 %1
7082    lwz%U1%X1 %0,%1
7083    stw%U0%X0 %1,%0"
7084   [(set (attr "type")
7085      (cond [(eq_attr "alternative" "0,3")
7086                 (const_string "cr_logical")
7087             (eq_attr "alternative" "1,2")
7088                 (const_string "mtcr")
7089             (eq_attr "alternative" "6,7")
7090                 (const_string "integer")
7091             (eq_attr "alternative" "8")
7092                 (const_string "mfjmpr")
7093             (eq_attr "alternative" "9")
7094                 (const_string "mtjmpr")
7095             (eq_attr "alternative" "10")
7096                 (const_string "load")
7097             (eq_attr "alternative" "11")
7098                 (const_string "store")
7099             (match_test "TARGET_MFCRF")
7100                 (const_string "mfcrf")
7101            ]
7102         (const_string "mfcr")))
7103    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7105 ;; For floating-point, we normally deal with the floating-point registers
7106 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7107 ;; can produce floating-point values in fixed-point registers.  Unless the
7108 ;; value is a simple constant or already in memory, we deal with this by
7109 ;; allocating memory and copying the value explicitly via that memory location.
7111 ;; Move 32-bit binary/decimal floating point
7112 (define_expand "mov<mode>"
7113   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7114         (match_operand:FMOVE32 1 "any_operand" ""))]
7115   "<fmove_ok>"
7116   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7118 (define_split
7119   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7120         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7121   "reload_completed
7122    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7123        || (GET_CODE (operands[0]) == SUBREG
7124            && GET_CODE (SUBREG_REG (operands[0])) == REG
7125            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7126   [(set (match_dup 2) (match_dup 3))]
7127   "
7129   long l;
7131   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7133   if (! TARGET_POWERPC64)
7134     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7135   else
7136     operands[2] = gen_lowpart (SImode, operands[0]);
7138   operands[3] = gen_int_mode (l, SImode);
7141 (define_insn "mov<mode>_hardfloat"
7142   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7143          "=!r,       <f32_lr>,  <f32_lr2>, <f32_av>,  m,         <f32_sm>,
7144           <f32_sm2>, Z,         <f32_vsx>, !r,        ?<f32_dm>, ?r,
7145           f,         <f32_vsx>, !r,        *c*l,      !r,        *h")
7146         (match_operand:FMOVE32 1 "input_operand"
7147          "m,         <f32_lm>,  <f32_lm2>, Z,         r,         <f32_sr>,
7148           <f32_sr2>, <f32_av>,  <zero_fp>, <zero_fp>, r,         <f32_dm>,
7149           f,         <f32_vsx>, r,         r,         *h,        0"))]
7150   "(register_operand (operands[0], <MODE>mode)
7151    || register_operand (operands[1], <MODE>mode))
7152    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7153    && (TARGET_ALLOW_SF_SUBREG
7154        || valid_sf_si_move (operands[0], operands[1], <MODE>mode))"
7155   "@
7156    lwz%U1%X1 %0,%1
7157    <f32_li>
7158    <f32_li2>
7159    <f32_lv>
7160    stw%U0%X0 %1,%0
7161    <f32_si>
7162    <f32_si2>
7163    <f32_sv>
7164    xxlxor %x0,%x0,%x0
7165    li %0,0
7166    mtvsrwz %x0,%1
7167    mfvsrwz %0,%x1
7168    fmr %0,%1
7169    xscpsgndp %x0,%x1,%x1
7170    mr %0,%1
7171    mt%0 %1
7172    mf%1 %0
7173    nop"
7174   [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
7176 (define_insn "*mov<mode>_softfloat"
7177   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7178         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7179   "(gpc_reg_operand (operands[0], <MODE>mode)
7180    || gpc_reg_operand (operands[1], <MODE>mode))
7181    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7182   "@
7183    mr %0,%1
7184    mt%0 %1
7185    mf%1 %0
7186    lwz%U1%X1 %0,%1
7187    stw%U0%X0 %1,%0
7188    li %0,%1
7189    lis %0,%v1
7190    #
7191    #
7192    nop"
7193   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7194    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7196 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7197 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7199 ;; Because SF values are actually stored as DF values within the vector
7200 ;; registers, we need to convert the value to the vector SF format when
7201 ;; we need to use the bits in a union or similar cases.  We only need
7202 ;; to do this transformation when the value is a vector register.  Loads,
7203 ;; stores, and transfers within GPRs are assumed to be safe.
7205 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7206 ;; no alternatives, because the call is created as part of secondary_reload,
7207 ;; and operand #2's register class is used to allocate the temporary register.
7208 ;; This function is called before reload, and it creates the temporary as
7209 ;; needed.
7211 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7212 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7213 (define_insn_and_split "movsf_from_si"
7214   [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7215             "=!r,       f,         wb,        wu,        m,         Z,
7216              Z,         wy,        ?r,        !r")
7218         (unspec:SF [(match_operand:SI 1 "input_operand" 
7219             "m,         m,         wY,        Z,         r,         f,
7220              wu,        r,         wy,        r")]
7221                    UNSPEC_SF_FROM_SI))
7223    (clobber (match_scratch:DI 2
7224             "=X,        X,         X,         X,         X,         X,
7225              X,         r,         X,         X"))]
7227   "TARGET_NO_SF_SUBREG
7228    && (register_operand (operands[0], SFmode)
7229        || register_operand (operands[1], SImode))"
7230   "@
7231    lwz%U1%X1 %0,%1
7232    lfs%U1%X1 %0,%1
7233    lxssp %0,%1
7234    lxsspx %x0,%y1
7235    stw%U0%X0 %1,%0
7236    stfiwx %1,%y0
7237    stxsiwx %x1,%y0
7238    #
7239    mfvsrwz %0,%x1
7240    mr %0,%1"
7242   "&& reload_completed
7243    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7244    && int_reg_operand_not_pseudo (operands[1], SImode)"
7245   [(const_int 0)]
7247   rtx op0 = operands[0];
7248   rtx op1 = operands[1];
7249   rtx op2 = operands[2];
7250   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7252   /* Move SF value to upper 32-bits for xscvspdpn.  */
7253   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7254   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7255   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7256   DONE;
7258   [(set_attr "length"
7259             "4,          4,         4,         4,         4,         4,
7260              4,          12,        4,         4")
7261    (set_attr "type"
7262             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7263              fpstore,    vecfloat,  mffgpr,    *")])
7266 ;; Move 64-bit binary/decimal floating point
7267 (define_expand "mov<mode>"
7268   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7269         (match_operand:FMOVE64 1 "any_operand" ""))]
7270   ""
7271   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7273 (define_split
7274   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7275         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7276   "! TARGET_POWERPC64 && reload_completed
7277    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7278        || (GET_CODE (operands[0]) == SUBREG
7279            && GET_CODE (SUBREG_REG (operands[0])) == REG
7280            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7281   [(set (match_dup 2) (match_dup 4))
7282    (set (match_dup 3) (match_dup 1))]
7283   "
7285   int endian = (WORDS_BIG_ENDIAN == 0);
7286   HOST_WIDE_INT value = INTVAL (operands[1]);
7288   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7289   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7290   operands[4] = GEN_INT (value >> 32);
7291   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7294 (define_split
7295   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7296         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7297   "! TARGET_POWERPC64 && reload_completed
7298    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7299        || (GET_CODE (operands[0]) == SUBREG
7300            && GET_CODE (SUBREG_REG (operands[0])) == REG
7301            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7302   [(set (match_dup 2) (match_dup 4))
7303    (set (match_dup 3) (match_dup 5))]
7304   "
7306   int endian = (WORDS_BIG_ENDIAN == 0);
7307   long l[2];
7309   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7311   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7312   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7313   operands[4] = gen_int_mode (l[endian], SImode);
7314   operands[5] = gen_int_mode (l[1 - endian], SImode);
7317 (define_split
7318   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7319         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7320   "TARGET_POWERPC64 && reload_completed
7321    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7322        || (GET_CODE (operands[0]) == SUBREG
7323            && GET_CODE (SUBREG_REG (operands[0])) == REG
7324            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7325   [(set (match_dup 2) (match_dup 3))]
7326   "
7328   int endian = (WORDS_BIG_ENDIAN == 0);
7329   long l[2];
7330   HOST_WIDE_INT val;
7332   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7334   operands[2] = gen_lowpart (DImode, operands[0]);
7335   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7336   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7337          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7339   operands[3] = gen_int_mode (val, DImode);
7342 ;; Don't have reload use general registers to load a constant.  It is
7343 ;; less efficient than loading the constant into an FP register, since
7344 ;; it will probably be used there.
7346 ;; The move constraints are ordered to prefer floating point registers before
7347 ;; general purpose registers to avoid doing a store and a load to get the value
7348 ;; into a floating point register when it is needed for a floating point
7349 ;; operation.  Prefer traditional floating point registers over VSX registers,
7350 ;; since the D-form version of the memory instructions does not need a GPR for
7351 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7352 ;; registers.
7354 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7355 ;; except for 0.0 which can be created on VSX with an xor instruction.
7357 (define_insn "*mov<mode>_hardfloat32"
7358   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7359         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7360   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7361    && (gpc_reg_operand (operands[0], <MODE>mode)
7362        || gpc_reg_operand (operands[1], <MODE>mode))"
7363   "@
7364    stfd%U0%X0 %1,%0
7365    lfd%U1%X1 %0,%1
7366    fmr %0,%1
7367    lxsd%U1x %x0,%y1
7368    stxsd%U0x %x1,%y0
7369    lxsd %0,%1
7370    stxsd %1,%0
7371    xxlor %x0,%x1,%x1
7372    xxlxor %x0,%x0,%x0
7373    #
7374    #
7375    #
7376    #"
7377   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7378    (set_attr "size" "64")
7379    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7381 (define_insn "*mov<mode>_softfloat32"
7382   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7383         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7384   "! TARGET_POWERPC64 
7385    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
7386        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7387        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7388    && (gpc_reg_operand (operands[0], <MODE>mode)
7389        || gpc_reg_operand (operands[1], <MODE>mode))"
7390   "#"
7391   [(set_attr "type" "store,load,two,*,*,*")
7392    (set_attr "length" "8,8,8,8,12,16")])
7394 ; ld/std require word-aligned displacements -> 'Y' constraint.
7395 ; List Y->r and r->Y before r->r for reload.
7396 (define_insn "*mov<mode>_hardfloat64"
7397   [(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>")
7398         (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"))]
7399   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7400    && (gpc_reg_operand (operands[0], <MODE>mode)
7401        || gpc_reg_operand (operands[1], <MODE>mode))"
7402   "@
7403    stfd%U0%X0 %1,%0
7404    lfd%U1%X1 %0,%1
7405    fmr %0,%1
7406    lxsd %0,%1
7407    stxsd %1,%0
7408    lxsd%U1x %x0,%y1
7409    stxsd%U0x %x1,%y0
7410    xxlor %x0,%x1,%x1
7411    xxlxor %x0,%x0,%x0
7412    li %0,0
7413    std%U0%X0 %1,%0
7414    ld%U1%X1 %0,%1
7415    mr %0,%1
7416    mt%0 %1
7417    mf%1 %0
7418    nop
7419    mftgpr %0,%1
7420    mffgpr %0,%1
7421    mfvsrd %0,%x1
7422    mtvsrd %x0,%1"
7423   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7424    (set_attr "size" "64")
7425    (set_attr "length" "4")])
7427 (define_insn "*mov<mode>_softfloat64"
7428   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7429         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7430   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7431    && (gpc_reg_operand (operands[0], <MODE>mode)
7432        || gpc_reg_operand (operands[1], <MODE>mode))"
7433   "@
7434    std%U0%X0 %1,%0
7435    ld%U1%X1 %0,%1
7436    mr %0,%1
7437    mt%0 %1
7438    mf%1 %0
7439    #
7440    #
7441    #
7442    nop"
7443   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7444    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7446 (define_expand "mov<mode>"
7447   [(set (match_operand:FMOVE128 0 "general_operand" "")
7448         (match_operand:FMOVE128 1 "any_operand" ""))]
7449   ""
7450   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7452 ;; It's important to list Y->r and r->Y before r->r because otherwise
7453 ;; reload, given m->r, will try to pick r->r and reload it, which
7454 ;; doesn't make progress.
7456 ;; We can't split little endian direct moves of TDmode, because the words are
7457 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7458 ;; problematical.  Don't allow direct move for this case.
7460 (define_insn_and_split "*mov<mode>_64bit_dm"
7461   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7462         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7463   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7464    && FLOAT128_2REG_P (<MODE>mode)
7465    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7466    && (gpc_reg_operand (operands[0], <MODE>mode)
7467        || gpc_reg_operand (operands[1], <MODE>mode))"
7468   "#"
7469   "&& reload_completed"
7470   [(pc)]
7471 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7472   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7474 (define_insn_and_split "*movtd_64bit_nodm"
7475   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7476         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7477   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7478    && (gpc_reg_operand (operands[0], TDmode)
7479        || gpc_reg_operand (operands[1], TDmode))"
7480   "#"
7481   "&& reload_completed"
7482   [(pc)]
7483 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7484   [(set_attr "length" "8,8,8,12,12,8")])
7486 (define_insn_and_split "*mov<mode>_32bit"
7487   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7488         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7489   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7490    && (FLOAT128_2REG_P (<MODE>mode)
7491        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7492        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7493    && (gpc_reg_operand (operands[0], <MODE>mode)
7494        || gpc_reg_operand (operands[1], <MODE>mode))"
7495   "#"
7496   "&& reload_completed"
7497   [(pc)]
7498 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7499   [(set_attr "length" "8,8,8,8,20,20,16")])
7501 (define_insn_and_split "*mov<mode>_softfloat"
7502   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7503         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7504   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7505    && (gpc_reg_operand (operands[0], <MODE>mode)
7506        || gpc_reg_operand (operands[1], <MODE>mode))"
7507   "#"
7508   "&& reload_completed"
7509   [(pc)]
7510 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7511   [(set_attr "length" "20,20,16")])
7513 (define_expand "extenddf<mode>2"
7514   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7515         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7516   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7517    && TARGET_LONG_DOUBLE_128"
7519   if (FLOAT128_IEEE_P (<MODE>mode))
7520     rs6000_expand_float128_convert (operands[0], operands[1], false);
7521   else if (TARGET_E500_DOUBLE)
7522     {
7523       gcc_assert (<MODE>mode == TFmode);
7524       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7525     }
7526   else if (TARGET_VSX)
7527     {
7528       if (<MODE>mode == TFmode)
7529         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7530       else if (<MODE>mode == IFmode)
7531         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7532       else
7533         gcc_unreachable ();
7534     }
7535    else
7536     {
7537       rtx zero = gen_reg_rtx (DFmode);
7538       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7540       if (<MODE>mode == TFmode)
7541         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7542       else if (<MODE>mode == IFmode)
7543         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7544       else
7545         gcc_unreachable ();
7546     }
7547   DONE;
7550 ;; Allow memory operands for the source to be created by the combiner.
7551 (define_insn_and_split "extenddf<mode>2_fprs"
7552   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7553         (float_extend:IBM128
7554          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7555    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7556   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7557    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7558   "#"
7559   "&& reload_completed"
7560   [(set (match_dup 3) (match_dup 1))
7561    (set (match_dup 4) (match_dup 2))]
7563   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7564   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7566   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7567   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7570 (define_insn_and_split "extenddf<mode>2_vsx"
7571   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7572         (float_extend:IBM128
7573          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7574   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7575   "#"
7576   "&& reload_completed"
7577   [(set (match_dup 2) (match_dup 1))
7578    (set (match_dup 3) (match_dup 4))]
7580   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7581   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7583   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7584   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7585   operands[4] = CONST0_RTX (DFmode);
7588 (define_expand "extendsf<mode>2"
7589   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7590         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7591   "TARGET_HARD_FLOAT
7592    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7593    && TARGET_LONG_DOUBLE_128"
7595   if (FLOAT128_IEEE_P (<MODE>mode))
7596     rs6000_expand_float128_convert (operands[0], operands[1], false);
7597   else
7598     {
7599       rtx tmp = gen_reg_rtx (DFmode);
7600       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7601       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7602     }
7603   DONE;
7606 (define_expand "trunc<mode>df2"
7607   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7608         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7609   "TARGET_HARD_FLOAT
7610    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7611    && TARGET_LONG_DOUBLE_128"
7613   if (FLOAT128_IEEE_P (<MODE>mode))
7614     {
7615       rs6000_expand_float128_convert (operands[0], operands[1], false);
7616       DONE;
7617     }
7620 (define_insn_and_split "trunc<mode>df2_internal1"
7621   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7622         (float_truncate:DF
7623          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7624   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7625    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7626   "@
7627    #
7628    fmr %0,%1"
7629   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7630   [(const_int 0)]
7632   emit_note (NOTE_INSN_DELETED);
7633   DONE;
7635   [(set_attr "type" "fpsimple")])
7637 (define_insn "trunc<mode>df2_internal2"
7638   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7639         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7640   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7641    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7642   "fadd %0,%1,%L1"
7643   [(set_attr "type" "fp")
7644    (set_attr "fp_type" "fp_addsub_d")])
7646 (define_expand "trunc<mode>sf2"
7647   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7648         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7649   "TARGET_HARD_FLOAT
7650    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7651    && TARGET_LONG_DOUBLE_128"
7653   if (FLOAT128_IEEE_P (<MODE>mode))
7654     rs6000_expand_float128_convert (operands[0], operands[1], false);
7655   else if (TARGET_E500_DOUBLE)
7656     {
7657       gcc_assert (<MODE>mode == TFmode);
7658       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7659     }
7660   else if (<MODE>mode == TFmode)
7661     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7662   else if (<MODE>mode == IFmode)
7663     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7664   else
7665     gcc_unreachable ();
7666   DONE;
7669 (define_insn_and_split "trunc<mode>sf2_fprs"
7670   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7671         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7672    (clobber (match_scratch:DF 2 "=d"))]
7673   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7674    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7675   "#"
7676   "&& reload_completed"
7677   [(set (match_dup 2)
7678         (float_truncate:DF (match_dup 1)))
7679    (set (match_dup 0)
7680         (float_truncate:SF (match_dup 2)))]
7681   "")
7683 (define_expand "floatsi<mode>2"
7684   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7685                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7686               (clobber (match_scratch:DI 2))])]
7687   "TARGET_HARD_FLOAT
7688    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7689    && TARGET_LONG_DOUBLE_128"
7691   rtx op0 = operands[0];
7692   rtx op1 = operands[1];
7694   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7695     ;
7696   else if (FLOAT128_IEEE_P (<MODE>mode))
7697     {
7698       rs6000_expand_float128_convert (op0, op1, false);
7699       DONE;
7700     }
7701   else
7702     {
7703       rtx tmp = gen_reg_rtx (DFmode);
7704       expand_float (tmp, op1, false);
7705       if (<MODE>mode == TFmode)
7706         emit_insn (gen_extenddftf2 (op0, tmp));
7707       else if (<MODE>mode == IFmode)
7708         emit_insn (gen_extenddfif2 (op0, tmp));
7709       else
7710         gcc_unreachable ();
7711       DONE;
7712     }
7715 ; fadd, but rounding towards zero.
7716 ; This is probably not the optimal code sequence.
7717 (define_insn "fix_trunc_helper<mode>"
7718   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7719         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7720                    UNSPEC_FIX_TRUNC_TF))
7721    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7722   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7723    && FLOAT128_IBM_P (<MODE>mode)"
7724   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7725   [(set_attr "type" "fp")
7726    (set_attr "length" "20")])
7728 (define_expand "fix_trunc<mode>si2"
7729   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7730         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7731   "TARGET_HARD_FLOAT
7732    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7734   rtx op0 = operands[0];
7735   rtx op1 = operands[1];
7737   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7738     ;
7739   else
7740     {
7741       if (FLOAT128_IEEE_P (<MODE>mode))
7742         rs6000_expand_float128_convert (op0, op1, false);
7743       else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7744         emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
7745       else if (<MODE>mode == TFmode)
7746         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7747       else if (<MODE>mode == IFmode)
7748         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7749       else
7750         gcc_unreachable ();
7751       DONE;
7752     }
7755 (define_expand "fix_trunc<mode>si2_fprs"
7756   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7757                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7758               (clobber (match_dup 2))
7759               (clobber (match_dup 3))
7760               (clobber (match_dup 4))
7761               (clobber (match_dup 5))])]
7762   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7764   operands[2] = gen_reg_rtx (DFmode);
7765   operands[3] = gen_reg_rtx (DFmode);
7766   operands[4] = gen_reg_rtx (DImode);
7767   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7770 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7771   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7772         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7773    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7774    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7775    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7776    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7777   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7778   "#"
7779   ""
7780   [(pc)]
7782   rtx lowword;
7783   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7784                                          operands[3]));
7786   gcc_assert (MEM_P (operands[5]));
7787   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7789   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7790   emit_move_insn (operands[5], operands[4]);
7791   emit_move_insn (operands[0], lowword);
7792   DONE;
7795 (define_expand "fix_trunc<mode>di2"
7796   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7797         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7798   "TARGET_FLOAT128_TYPE"
7800   if (!TARGET_FLOAT128_HW)
7801     {
7802       rs6000_expand_float128_convert (operands[0], operands[1], false);
7803       DONE;
7804     }
7807 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7808   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7809         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7810   "TARGET_FLOAT128_TYPE"
7812   rs6000_expand_float128_convert (operands[0], operands[1], true);
7813   DONE;
7816 (define_expand "floatdi<mode>2"
7817   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7818         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7819   "TARGET_FLOAT128_TYPE"
7821   if (!TARGET_FLOAT128_HW)
7822     {
7823       rs6000_expand_float128_convert (operands[0], operands[1], false);
7824       DONE;
7825     }
7828 (define_expand "floatunsdi<IEEE128:mode>2"
7829   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7830         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7831   "TARGET_FLOAT128_TYPE"
7833   if (!TARGET_FLOAT128_HW)
7834     {
7835       rs6000_expand_float128_convert (operands[0], operands[1], true);
7836       DONE;
7837     }
7840 (define_expand "floatuns<IEEE128:mode>2"
7841   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7842         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7843   "TARGET_FLOAT128_TYPE"
7845   rtx op0 = operands[0];
7846   rtx op1 = operands[1];
7848   if (TARGET_FLOAT128_HW)
7849     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7850   else
7851     rs6000_expand_float128_convert (op0, op1, true);
7852   DONE;
7855 (define_expand "neg<mode>2"
7856   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7857         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7858   "FLOAT128_IEEE_P (<MODE>mode)
7859    || (FLOAT128_IBM_P (<MODE>mode)
7860        && TARGET_HARD_FLOAT
7861        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7862   "
7864   if (FLOAT128_IEEE_P (<MODE>mode))
7865     {
7866       if (TARGET_FLOAT128_HW)
7867         {
7868           if (<MODE>mode == TFmode)
7869             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7870           else if (<MODE>mode == KFmode)
7871             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7872           else
7873             gcc_unreachable ();
7874         }
7875       else if (TARGET_FLOAT128_TYPE)
7876         {
7877           if (<MODE>mode == TFmode)
7878             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7879           else if (<MODE>mode == KFmode)
7880             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7881           else
7882             gcc_unreachable ();
7883         }
7884       else
7885         {
7886           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7887           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7888                                                 <MODE>mode, 1,
7889                                                 operands[1], <MODE>mode);
7891           if (target && !rtx_equal_p (target, operands[0]))
7892             emit_move_insn (operands[0], target);
7893         }
7894       DONE;
7895     }
7898 (define_insn "neg<mode>2_internal"
7899   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7900         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7901   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7902   "*
7904   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7905     return \"fneg %L0,%L1\;fneg %0,%1\";
7906   else
7907     return \"fneg %0,%1\;fneg %L0,%L1\";
7909   [(set_attr "type" "fpsimple")
7910    (set_attr "length" "8")])
7912 (define_expand "abs<mode>2"
7913   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7914         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7915   "FLOAT128_IEEE_P (<MODE>mode)
7916    || (FLOAT128_IBM_P (<MODE>mode)
7917        && TARGET_HARD_FLOAT
7918        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7919   "
7921   rtx label;
7923   if (FLOAT128_IEEE_P (<MODE>mode))
7924     {
7925       if (TARGET_FLOAT128_HW)
7926         {
7927           if (<MODE>mode == TFmode)
7928             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7929           else if (<MODE>mode == KFmode)
7930             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7931           else
7932             FAIL;
7933           DONE;
7934         }
7935       else if (TARGET_FLOAT128_TYPE)
7936         {
7937           if (<MODE>mode == TFmode)
7938             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7939           else if (<MODE>mode == KFmode)
7940             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7941           else
7942             FAIL;
7943           DONE;
7944         }
7945       else
7946         FAIL;
7947     }
7949   label = gen_label_rtx ();
7950   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7951     {
7952       if (flag_finite_math_only && !flag_trapping_math)
7953         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7954       else
7955         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7956     }
7957   else if (<MODE>mode == TFmode)
7958     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7959   else if (<MODE>mode == TFmode)
7960     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7961   else
7962     FAIL;
7963   emit_label (label);
7964   DONE;
7967 (define_expand "abs<mode>2_internal"
7968   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7969         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7970    (set (match_dup 3) (match_dup 5))
7971    (set (match_dup 5) (abs:DF (match_dup 5)))
7972    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7973    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7974                            (label_ref (match_operand 2 "" ""))
7975                            (pc)))
7976    (set (match_dup 6) (neg:DF (match_dup 6)))]
7977   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7978    && TARGET_LONG_DOUBLE_128"
7979   "
7981   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7982   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7983   operands[3] = gen_reg_rtx (DFmode);
7984   operands[4] = gen_reg_rtx (CCFPmode);
7985   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7986   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7990 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7991 ;; register
7993 (define_expand "ieee_128bit_negative_zero"
7994   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7995   "TARGET_FLOAT128_TYPE"
7997   rtvec v = rtvec_alloc (16);
7998   int i, high;
8000   for (i = 0; i < 16; i++)
8001     RTVEC_ELT (v, i) = const0_rtx;
8003   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8004   RTVEC_ELT (v, high) = GEN_INT (0x80);
8006   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8007   DONE;
8010 ;; IEEE 128-bit negate
8012 ;; We have 2 insns here for negate and absolute value.  The first uses
8013 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8014 ;; insns, and second insn after the first split pass loads up the bit to
8015 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8016 ;; neg/abs to create the constant just once.
8018 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8019   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8020         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8021    (clobber (match_scratch:V16QI 2 "=v"))]
8022   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8023   "#"
8024   "&& 1"
8025   [(parallel [(set (match_dup 0)
8026                    (neg:IEEE128 (match_dup 1)))
8027               (use (match_dup 2))])]
8029   if (GET_CODE (operands[2]) == SCRATCH)
8030     operands[2] = gen_reg_rtx (V16QImode);
8032   operands[3] = gen_reg_rtx (V16QImode);
8033   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8035   [(set_attr "length" "8")
8036    (set_attr "type" "vecsimple")])
8038 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8039   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8040         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8041    (use (match_operand:V16QI 2 "register_operand" "v"))]
8042   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8043   "xxlxor %x0,%x1,%x2"
8044   [(set_attr "type" "veclogical")])
8046 ;; IEEE 128-bit absolute value
8047 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8048   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8049         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8050    (clobber (match_scratch:V16QI 2 "=v"))]
8051   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8052   "#"
8053   "&& 1"
8054   [(parallel [(set (match_dup 0)
8055                    (abs:IEEE128 (match_dup 1)))
8056               (use (match_dup 2))])]
8058   if (GET_CODE (operands[2]) == SCRATCH)
8059     operands[2] = gen_reg_rtx (V16QImode);
8061   operands[3] = gen_reg_rtx (V16QImode);
8062   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8064   [(set_attr "length" "8")
8065    (set_attr "type" "vecsimple")])
8067 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8068   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8069         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8070    (use (match_operand:V16QI 2 "register_operand" "v"))]
8071   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8072   "xxlandc %x0,%x1,%x2"
8073   [(set_attr "type" "veclogical")])
8075 ;; IEEE 128-bit negative absolute value
8076 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8077   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8078         (neg:IEEE128
8079          (abs:IEEE128
8080           (match_operand:IEEE128 1 "register_operand" "wa"))))
8081    (clobber (match_scratch:V16QI 2 "=v"))]
8082   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8083    && FLOAT128_IEEE_P (<MODE>mode)"
8084   "#"
8085   "&& 1"
8086   [(parallel [(set (match_dup 0)
8087                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8088               (use (match_dup 2))])]
8090   if (GET_CODE (operands[2]) == SCRATCH)
8091     operands[2] = gen_reg_rtx (V16QImode);
8093   operands[3] = gen_reg_rtx (V16QImode);
8094   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8096   [(set_attr "length" "8")
8097    (set_attr "type" "vecsimple")])
8099 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8100   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8101         (neg:IEEE128
8102          (abs:IEEE128
8103           (match_operand:IEEE128 1 "register_operand" "wa"))))
8104    (use (match_operand:V16QI 2 "register_operand" "v"))]
8105   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8106   "xxlor %x0,%x1,%x2"
8107   [(set_attr "type" "veclogical")])
8109 ;; Float128 conversion functions.  These expand to library function calls.
8110 ;; We use expand to convert from IBM double double to IEEE 128-bit
8111 ;; and trunc for the opposite.
8112 (define_expand "extendiftf2"
8113   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8114         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8115   "TARGET_FLOAT128_TYPE"
8117   rs6000_expand_float128_convert (operands[0], operands[1], false);
8118   DONE;
8121 (define_expand "extendifkf2"
8122   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8123         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8124   "TARGET_FLOAT128_TYPE"
8126   rs6000_expand_float128_convert (operands[0], operands[1], false);
8127   DONE;
8130 (define_expand "extendtfkf2"
8131   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8132         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8133   "TARGET_FLOAT128_TYPE"
8135   rs6000_expand_float128_convert (operands[0], operands[1], false);
8136   DONE;
8139 (define_expand "trunciftf2"
8140   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8141         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8142   "TARGET_FLOAT128_TYPE"
8144   rs6000_expand_float128_convert (operands[0], operands[1], false);
8145   DONE;
8148 (define_expand "truncifkf2"
8149   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8150         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8151   "TARGET_FLOAT128_TYPE"
8153   rs6000_expand_float128_convert (operands[0], operands[1], false);
8154   DONE;
8157 (define_expand "trunckftf2"
8158   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8159         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8160   "TARGET_FLOAT128_TYPE"
8162   rs6000_expand_float128_convert (operands[0], operands[1], false);
8163   DONE;
8166 (define_expand "trunctfif2"
8167   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8168         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8169   "TARGET_FLOAT128_TYPE"
8171   rs6000_expand_float128_convert (operands[0], operands[1], false);
8172   DONE;
8176 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8177 ;; must have 3 arguments, and scratch register constraint must be a single
8178 ;; constraint.
8180 ;; Reload patterns to support gpr load/store with misaligned mem.
8181 ;; and multiple gpr load/store at offset >= 0xfffc
8182 (define_expand "reload_<mode>_store"
8183   [(parallel [(match_operand 0 "memory_operand" "=m")
8184               (match_operand 1 "gpc_reg_operand" "r")
8185               (match_operand:GPR 2 "register_operand" "=&b")])]
8186   ""
8188   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8189   DONE;
8192 (define_expand "reload_<mode>_load"
8193   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8194               (match_operand 1 "memory_operand" "m")
8195               (match_operand:GPR 2 "register_operand" "=b")])]
8196   ""
8198   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8199   DONE;
8203 ;; Reload patterns for various types using the vector registers.  We may need
8204 ;; an additional base register to convert the reg+offset addressing to reg+reg
8205 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8206 ;; index register for gpr registers.
8207 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8208   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8209               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8210               (match_operand:P 2 "register_operand" "=b")])]
8211   "<P:tptrsize>"
8213   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8214   DONE;
8217 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8218   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8219               (match_operand:RELOAD 1 "memory_operand" "m")
8220               (match_operand:P 2 "register_operand" "=b")])]
8221   "<P:tptrsize>"
8223   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8224   DONE;
8228 ;; Reload sometimes tries to move the address to a GPR, and can generate
8229 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8230 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8232 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8233   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8234         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8235                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8236                (const_int -16)))]
8237   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8238   "#"
8239   "&& reload_completed"
8240   [(set (match_dup 0)
8241         (plus:P (match_dup 1)
8242                 (match_dup 2)))
8243    (set (match_dup 0)
8244         (and:P (match_dup 0)
8245                (const_int -16)))])
8247 ;; Power8 merge instructions to allow direct move to/from floating point
8248 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8249 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8250 ;; value, since it is allocated in reload and not all of the flow information
8251 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8252 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8253 ;; schedule other instructions between the two instructions.
8255 (define_insn "p8_fmrgow_<mode>"
8256   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8257         (unspec:FMOVE64X [
8258                 (match_operand:DF 1 "register_operand" "d")
8259                 (match_operand:DF 2 "register_operand" "d")]
8260                          UNSPEC_P8V_FMRGOW))]
8261   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8262   "fmrgow %0,%1,%2"
8263   [(set_attr "type" "fpsimple")])
8265 (define_insn "p8_mtvsrwz"
8266   [(set (match_operand:DF 0 "register_operand" "=d")
8267         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8268                    UNSPEC_P8V_MTVSRWZ))]
8269   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8270   "mtvsrwz %x0,%1"
8271   [(set_attr "type" "mftgpr")])
8273 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8274   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8275         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8276                          UNSPEC_P8V_RELOAD_FROM_GPR))
8277    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8278   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8279   "#"
8280   "&& reload_completed"
8281   [(const_int 0)]
8283   rtx dest = operands[0];
8284   rtx src = operands[1];
8285   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8286   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8287   rtx gpr_hi_reg = gen_highpart (SImode, src);
8288   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8290   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8291   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8292   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8293   DONE;
8295   [(set_attr "length" "12")
8296    (set_attr "type" "three")])
8298 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8299 (define_insn "p8_mtvsrd_df"
8300   [(set (match_operand:DF 0 "register_operand" "=wa")
8301         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8302                    UNSPEC_P8V_MTVSRD))]
8303   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8304   "mtvsrd %x0,%1"
8305   [(set_attr "type" "mftgpr")])
8307 (define_insn "p8_xxpermdi_<mode>"
8308   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8309         (unspec:FMOVE128_GPR [
8310                 (match_operand:DF 1 "register_operand" "wa")
8311                 (match_operand:DF 2 "register_operand" "wa")]
8312                 UNSPEC_P8V_XXPERMDI))]
8313   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8314   "xxpermdi %x0,%x1,%x2,0"
8315   [(set_attr "type" "vecperm")])
8317 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8318   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8319         (unspec:FMOVE128_GPR
8320          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8321          UNSPEC_P8V_RELOAD_FROM_GPR))
8322    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8323   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8324   "#"
8325   "&& reload_completed"
8326   [(const_int 0)]
8328   rtx dest = operands[0];
8329   rtx src = operands[1];
8330   /* You might think that we could use op0 as one temp and a DF clobber
8331      as op2, but you'd be wrong.  Secondary reload move patterns don't
8332      check for overlap of the clobber and the destination.  */
8333   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8334   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8335   rtx gpr_hi_reg = gen_highpart (DImode, src);
8336   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8338   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8339   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8340   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8341   DONE;
8343   [(set_attr "length" "12")
8344    (set_attr "type" "three")])
8346 (define_split
8347   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8348         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8349   "reload_completed
8350    && (int_reg_operand (operands[0], <MODE>mode)
8351        || int_reg_operand (operands[1], <MODE>mode))
8352    && (!TARGET_DIRECT_MOVE_128
8353        || (!vsx_register_operand (operands[0], <MODE>mode)
8354            && !vsx_register_operand (operands[1], <MODE>mode)))"
8355   [(pc)]
8356 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8358 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8359 ;; type is stored internally as double precision in the VSX registers, we have
8360 ;; to convert it from the vector format.
8361 (define_insn "p8_mtvsrd_sf"
8362   [(set (match_operand:SF 0 "register_operand" "=wa")
8363         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8364                    UNSPEC_P8V_MTVSRD))]
8365   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8366   "mtvsrd %x0,%1"
8367   [(set_attr "type" "mftgpr")])
8369 (define_insn_and_split "reload_vsx_from_gprsf"
8370   [(set (match_operand:SF 0 "register_operand" "=wa")
8371         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8372                    UNSPEC_P8V_RELOAD_FROM_GPR))
8373    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8374   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8375   "#"
8376   "&& reload_completed"
8377   [(const_int 0)]
8379   rtx op0 = operands[0];
8380   rtx op1 = operands[1];
8381   rtx op2 = operands[2];
8382   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8384   /* Move SF value to upper 32-bits for xscvspdpn.  */
8385   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8386   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8387   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8388   DONE;
8390   [(set_attr "length" "8")
8391    (set_attr "type" "two")])
8393 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8394 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8395 ;; and then doing a move of that.
8396 (define_insn "p8_mfvsrd_3_<mode>"
8397   [(set (match_operand:DF 0 "register_operand" "=r")
8398         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8399                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8400   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8401   "mfvsrd %0,%x1"
8402   [(set_attr "type" "mftgpr")])
8404 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8405   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8406         (unspec:FMOVE128_GPR
8407          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8408          UNSPEC_P8V_RELOAD_FROM_VSX))
8409    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8410   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8411   "#"
8412   "&& reload_completed"
8413   [(const_int 0)]
8415   rtx dest = operands[0];
8416   rtx src = operands[1];
8417   rtx tmp = operands[2];
8418   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8419   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8421   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8422   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8423   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8424   DONE;
8426   [(set_attr "length" "12")
8427    (set_attr "type" "three")])
8429 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8430 ;; type is stored internally as double precision, we have to convert it to the
8431 ;; vector format.
8433 (define_insn_and_split "reload_gpr_from_vsxsf"
8434   [(set (match_operand:SF 0 "register_operand" "=r")
8435         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8436                    UNSPEC_P8V_RELOAD_FROM_VSX))
8437    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8438   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8439   "#"
8440   "&& reload_completed"
8441   [(const_int 0)]
8443   rtx op0 = operands[0];
8444   rtx op1 = operands[1];
8445   rtx op2 = operands[2];
8446   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8448   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8449   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8450   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8451   DONE;
8453   [(set_attr "length" "12")
8454    (set_attr "type" "three")])
8456 (define_insn "p8_mfvsrd_4_disf"
8457   [(set (match_operand:DI 0 "register_operand" "=r")
8458         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8459                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8460   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8461   "mfvsrd %0,%x1"
8462   [(set_attr "type" "mftgpr")])
8465 ;; Next come the multi-word integer load and store and the load and store
8466 ;; multiple insns.
8468 ;; List r->r after r->Y, otherwise reload will try to reload a
8469 ;; non-offsettable address by using r->r which won't make progress.
8470 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8471 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8473 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8474 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8475 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8476 ;;        AVX const  
8478 (define_insn "*movdi_internal32"
8479   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8480          "=Y,        r,         r,         ^m,        ^d,         ^d,
8481           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8482           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8483           *wv")
8485         (match_operand:DI 1 "input_operand"
8486           "r,        Y,         r,         d,         m,          d,
8487            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8488            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8489            wB"))]
8491   "! TARGET_POWERPC64
8492    && (gpc_reg_operand (operands[0], DImode)
8493        || gpc_reg_operand (operands[1], DImode))"
8494   "@
8495    #
8496    #
8497    #
8498    stfd%U0%X0 %1,%0
8499    lfd%U1%X1 %0,%1
8500    fmr %0,%1
8501    #
8502    stxsd %1,%0
8503    stxsdx %x1,%y0
8504    lxsd %0,%1
8505    lxsdx %x0,%y1
8506    xxlor %x0,%x1,%x1
8507    xxspltib %x0,0
8508    xxspltib %x0,255
8509    vspltisw %0,%1
8510    xxlxor %x0,%x0,%x0
8511    xxlorc %x0,%x0,%x0
8512    #
8513    #"
8514   [(set_attr "type"
8515                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8516                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8517                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8518                 vecsimple")
8519    (set_attr "size" "64")])
8521 (define_split
8522   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8523         (match_operand:DI 1 "const_int_operand" ""))]
8524   "! TARGET_POWERPC64 && reload_completed
8525    && gpr_or_gpr_p (operands[0], operands[1])
8526    && !direct_move_p (operands[0], operands[1])"
8527   [(set (match_dup 2) (match_dup 4))
8528    (set (match_dup 3) (match_dup 1))]
8529   "
8531   HOST_WIDE_INT value = INTVAL (operands[1]);
8532   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8533                                        DImode);
8534   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8535                                        DImode);
8536   operands[4] = GEN_INT (value >> 32);
8537   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8540 (define_split
8541   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8542         (match_operand:DIFD 1 "input_operand" ""))]
8543   "reload_completed && !TARGET_POWERPC64
8544    && gpr_or_gpr_p (operands[0], operands[1])
8545    && !direct_move_p (operands[0], operands[1])"
8546   [(pc)]
8547 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8549 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8550 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8551 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8552 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8553 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8554 (define_insn "*movdi_internal64"
8555   [(set (match_operand:DI 0 "nonimmediate_operand"
8556                "=Y,        r,         r,         r,         r,          r,
8557                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8558                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8559                 *wi,       *wv,       *wv,       r,         *h,         *h,
8560                 ?*r,       ?*wg,      ?*r,       ?*wj")
8562         (match_operand:DI 1 "input_operand"
8563                 "r,        Y,         r,         I,         L,          nF,
8564                  d,        m,         d,         wb,        wv,         wY,
8565                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8566                  wM,       wS,        wB,        *h,        r,          0,
8567                  wg,       r,         wj,        r"))]
8569   "TARGET_POWERPC64
8570    && (gpc_reg_operand (operands[0], DImode)
8571        || gpc_reg_operand (operands[1], DImode))"
8572   "@
8573    std%U0%X0 %1,%0
8574    ld%U1%X1 %0,%1
8575    mr %0,%1
8576    li %0,%1
8577    lis %0,%v1
8578    #
8579    stfd%U0%X0 %1,%0
8580    lfd%U1%X1 %0,%1
8581    fmr %0,%1
8582    stxsd %1,%0
8583    stxsdx %x1,%y0
8584    lxsd %0,%1
8585    lxsdx %x0,%y1
8586    xxlor %x0,%x1,%x1
8587    xxspltib %x0,0
8588    xxspltib %x0,255
8589    #
8590    xxlxor %x0,%x0,%x0
8591    xxlorc %x0,%x0,%x0
8592    #
8593    #
8594    mf%1 %0
8595    mt%0 %1
8596    nop
8597    mftgpr %0,%1
8598    mffgpr %0,%1
8599    mfvsrd %0,%x1
8600    mtvsrd %x0,%1"
8601   [(set_attr "type"
8602                "store,      load,       *,         *,         *,         *,
8603                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8604                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8605                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8606                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8608    (set_attr "size" "64")
8609    (set_attr "length"
8610                "4,         4,         4,         4,         4,          20,
8611                 4,         4,         4,         4,         4,          4,
8612                 4,         4,         4,         4,         4,          8,
8613                 8,         4,         4,         4,         4,          4,
8614                 4,         4,         4,         4")])
8616 ; Some DImode loads are best done as a load of -1 followed by a mask
8617 ; instruction.
8618 (define_split
8619   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8620         (match_operand:DI 1 "const_int_operand"))]
8621   "TARGET_POWERPC64
8622    && num_insns_constant (operands[1], DImode) > 1
8623    && rs6000_is_valid_and_mask (operands[1], DImode)"
8624   [(set (match_dup 0)
8625         (const_int -1))
8626    (set (match_dup 0)
8627         (and:DI (match_dup 0)
8628                 (match_dup 1)))]
8629   "")
8631 ;; Split a load of a large constant into the appropriate five-instruction
8632 ;; sequence.  Handle anything in a constant number of insns.
8633 ;; When non-easy constants can go in the TOC, this should use
8634 ;; easy_fp_constant predicate.
8635 (define_split
8636   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8637         (match_operand:DI 1 "const_int_operand" ""))]
8638   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8639   [(set (match_dup 0) (match_dup 2))
8640    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8641   "
8643   if (rs6000_emit_set_const (operands[0], operands[1]))
8644     DONE;
8645   else
8646     FAIL;
8649 (define_split
8650   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8651         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8652   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8653   [(set (match_dup 0) (match_dup 2))
8654    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8655   "
8657   if (rs6000_emit_set_const (operands[0], operands[1]))
8658     DONE;
8659   else
8660     FAIL;
8663 (define_split
8664   [(set (match_operand:DI 0 "altivec_register_operand" "")
8665         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8666   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8667   [(const_int 0)]
8669   rtx op0 = operands[0];
8670   rtx op1 = operands[1];
8671   int r = REGNO (op0);
8672   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8674   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8675   if (op1 != const0_rtx && op1 != constm1_rtx)
8676     {
8677       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8678       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8679     }
8680   DONE;
8683 ;; Split integer constants that can be loaded with XXSPLTIB and a
8684 ;; sign extend operation.
8685 (define_split
8686   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8687         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8688   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8689   [(const_int 0)]
8691   rtx op0 = operands[0];
8692   rtx op1 = operands[1];
8693   int r = REGNO (op0);
8694   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8696   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8697   if (<MODE>mode == DImode)
8698     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8699   else if (<MODE>mode == SImode)
8700     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8701   else if (<MODE>mode == HImode)
8702     {
8703       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8704       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8705     }
8706   DONE;
8710 ;; TImode/PTImode is similar, except that we usually want to compute the
8711 ;; address into a register and use lsi/stsi (the exception is during reload).
8713 (define_insn "*mov<mode>_string"
8714   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8715         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8716   "! TARGET_POWERPC64
8717    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8718    && (gpc_reg_operand (operands[0], <MODE>mode)
8719        || gpc_reg_operand (operands[1], <MODE>mode))"
8720   "*
8722   switch (which_alternative)
8723     {
8724     default:
8725       gcc_unreachable ();
8726     case 0:
8727       if (TARGET_STRING)
8728         return \"stswi %1,%P0,16\";
8729       /* FALLTHRU */
8730     case 1:
8731       return \"#\";
8732     case 2:
8733       /* If the address is not used in the output, we can use lsi.  Otherwise,
8734          fall through to generating four loads.  */
8735       if (TARGET_STRING
8736           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8737         return \"lswi %0,%P1,16\";
8738       /* fall through */
8739     case 3:
8740     case 4:
8741     case 5:
8742       return \"#\";
8743     }
8745   [(set_attr "type" "store,store,load,load,*,*")
8746    (set_attr "update" "yes")
8747    (set_attr "indexed" "yes")
8748    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8749                                           (const_string "always")
8750                                           (const_string "conditional")))])
8752 (define_insn "*mov<mode>_ppc64"
8753   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8754         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8755   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8756    && (gpc_reg_operand (operands[0], <MODE>mode)
8757        || gpc_reg_operand (operands[1], <MODE>mode)))"
8759   return rs6000_output_move_128bit (operands);
8761   [(set_attr "type" "store,store,load,load,*,*")
8762    (set_attr "length" "8")])
8764 (define_split
8765   [(set (match_operand:TI2 0 "int_reg_operand" "")
8766         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8767   "TARGET_POWERPC64
8768    && (VECTOR_MEM_NONE_P (<MODE>mode)
8769        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8770   [(set (match_dup 2) (match_dup 4))
8771    (set (match_dup 3) (match_dup 5))]
8772   "
8774   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8775                                        <MODE>mode);
8776   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8777                                        <MODE>mode);
8778   if (CONST_WIDE_INT_P (operands[1]))
8779     {
8780       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8781       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8782     }
8783   else if (CONST_INT_P (operands[1]))
8784     {
8785       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8786       operands[5] = operands[1];
8787     }
8788   else
8789     FAIL;
8792 (define_split
8793   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8794         (match_operand:TI2 1 "input_operand" ""))]
8795   "reload_completed
8796    && gpr_or_gpr_p (operands[0], operands[1])
8797    && !direct_move_p (operands[0], operands[1])
8798    && !quad_load_store_p (operands[0], operands[1])"
8799   [(pc)]
8800 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8802 (define_expand "load_multiple"
8803   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8804                           (match_operand:SI 1 "" ""))
8805                      (use (match_operand:SI 2 "" ""))])]
8806   "TARGET_STRING && !TARGET_POWERPC64"
8807   "
8809   int regno;
8810   int count;
8811   rtx op1;
8812   int i;
8814   /* Support only loading a constant number of fixed-point registers from
8815      memory and only bother with this if more than two; the machine
8816      doesn't support more than eight.  */
8817   if (GET_CODE (operands[2]) != CONST_INT
8818       || INTVAL (operands[2]) <= 2
8819       || INTVAL (operands[2]) > 8
8820       || GET_CODE (operands[1]) != MEM
8821       || GET_CODE (operands[0]) != REG
8822       || REGNO (operands[0]) >= 32)
8823     FAIL;
8825   count = INTVAL (operands[2]);
8826   regno = REGNO (operands[0]);
8828   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8829   op1 = replace_equiv_address (operands[1],
8830                                force_reg (SImode, XEXP (operands[1], 0)));
8832   for (i = 0; i < count; i++)
8833     XVECEXP (operands[3], 0, i)
8834       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8835                      adjust_address_nv (op1, SImode, i * 4));
8838 (define_insn "*ldmsi8"
8839   [(match_parallel 0 "load_multiple_operation"
8840     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8841           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8842      (set (match_operand:SI 3 "gpc_reg_operand" "")
8843           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8844      (set (match_operand:SI 4 "gpc_reg_operand" "")
8845           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8846      (set (match_operand:SI 5 "gpc_reg_operand" "")
8847           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8848      (set (match_operand:SI 6 "gpc_reg_operand" "")
8849           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8850      (set (match_operand:SI 7 "gpc_reg_operand" "")
8851           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8852      (set (match_operand:SI 8 "gpc_reg_operand" "")
8853           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8854      (set (match_operand:SI 9 "gpc_reg_operand" "")
8855           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8856   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8857   "*
8858 { return rs6000_output_load_multiple (operands); }"
8859   [(set_attr "type" "load")
8860    (set_attr "update" "yes")
8861    (set_attr "indexed" "yes")
8862    (set_attr "length" "32")])
8864 (define_insn "*ldmsi7"
8865   [(match_parallel 0 "load_multiple_operation"
8866     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8867           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8868      (set (match_operand:SI 3 "gpc_reg_operand" "")
8869           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8870      (set (match_operand:SI 4 "gpc_reg_operand" "")
8871           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8872      (set (match_operand:SI 5 "gpc_reg_operand" "")
8873           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8874      (set (match_operand:SI 6 "gpc_reg_operand" "")
8875           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8876      (set (match_operand:SI 7 "gpc_reg_operand" "")
8877           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8878      (set (match_operand:SI 8 "gpc_reg_operand" "")
8879           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8880   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8881   "*
8882 { return rs6000_output_load_multiple (operands); }"
8883   [(set_attr "type" "load")
8884    (set_attr "update" "yes")
8885    (set_attr "indexed" "yes")
8886    (set_attr "length" "32")])
8888 (define_insn "*ldmsi6"
8889   [(match_parallel 0 "load_multiple_operation"
8890     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8891           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8892      (set (match_operand:SI 3 "gpc_reg_operand" "")
8893           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8894      (set (match_operand:SI 4 "gpc_reg_operand" "")
8895           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8896      (set (match_operand:SI 5 "gpc_reg_operand" "")
8897           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8898      (set (match_operand:SI 6 "gpc_reg_operand" "")
8899           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8900      (set (match_operand:SI 7 "gpc_reg_operand" "")
8901           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8902   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8903   "*
8904 { return rs6000_output_load_multiple (operands); }"
8905   [(set_attr "type" "load")
8906    (set_attr "update" "yes")
8907    (set_attr "indexed" "yes")
8908    (set_attr "length" "32")])
8910 (define_insn "*ldmsi5"
8911   [(match_parallel 0 "load_multiple_operation"
8912     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8913           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8914      (set (match_operand:SI 3 "gpc_reg_operand" "")
8915           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8916      (set (match_operand:SI 4 "gpc_reg_operand" "")
8917           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8918      (set (match_operand:SI 5 "gpc_reg_operand" "")
8919           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8920      (set (match_operand:SI 6 "gpc_reg_operand" "")
8921           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8922   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8923   "*
8924 { return rs6000_output_load_multiple (operands); }"
8925   [(set_attr "type" "load")
8926    (set_attr "update" "yes")
8927    (set_attr "indexed" "yes")
8928    (set_attr "length" "32")])
8930 (define_insn "*ldmsi4"
8931   [(match_parallel 0 "load_multiple_operation"
8932     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8933           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8934      (set (match_operand:SI 3 "gpc_reg_operand" "")
8935           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8936      (set (match_operand:SI 4 "gpc_reg_operand" "")
8937           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8938      (set (match_operand:SI 5 "gpc_reg_operand" "")
8939           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8940   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8941   "*
8942 { return rs6000_output_load_multiple (operands); }"
8943   [(set_attr "type" "load")
8944    (set_attr "update" "yes")
8945    (set_attr "indexed" "yes")
8946    (set_attr "length" "32")])
8948 (define_insn "*ldmsi3"
8949   [(match_parallel 0 "load_multiple_operation"
8950     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8951           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8952      (set (match_operand:SI 3 "gpc_reg_operand" "")
8953           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8954      (set (match_operand:SI 4 "gpc_reg_operand" "")
8955           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8956   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8957   "*
8958 { return rs6000_output_load_multiple (operands); }"
8959   [(set_attr "type" "load")
8960    (set_attr "update" "yes")
8961    (set_attr "indexed" "yes")
8962    (set_attr "length" "32")])
8964 (define_expand "store_multiple"
8965   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8966                           (match_operand:SI 1 "" ""))
8967                      (clobber (scratch:SI))
8968                      (use (match_operand:SI 2 "" ""))])]
8969   "TARGET_STRING && !TARGET_POWERPC64"
8970   "
8972   int regno;
8973   int count;
8974   rtx to;
8975   rtx op0;
8976   int i;
8978   /* Support only storing a constant number of fixed-point registers to
8979      memory and only bother with this if more than two; the machine
8980      doesn't support more than eight.  */
8981   if (GET_CODE (operands[2]) != CONST_INT
8982       || INTVAL (operands[2]) <= 2
8983       || INTVAL (operands[2]) > 8
8984       || GET_CODE (operands[0]) != MEM
8985       || GET_CODE (operands[1]) != REG
8986       || REGNO (operands[1]) >= 32)
8987     FAIL;
8989   count = INTVAL (operands[2]);
8990   regno = REGNO (operands[1]);
8992   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8993   to = force_reg (SImode, XEXP (operands[0], 0));
8994   op0 = replace_equiv_address (operands[0], to);
8996   XVECEXP (operands[3], 0, 0)
8997     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8998   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8999                                                  gen_rtx_SCRATCH (SImode));
9001   for (i = 1; i < count; i++)
9002     XVECEXP (operands[3], 0, i + 1)
9003       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9004                      gen_rtx_REG (SImode, regno + i));
9007 (define_insn "*stmsi8"
9008   [(match_parallel 0 "store_multiple_operation"
9009     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9010           (match_operand:SI 2 "gpc_reg_operand" "r"))
9011      (clobber (match_scratch:SI 3 "=X"))
9012      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9013           (match_operand:SI 4 "gpc_reg_operand" "r"))
9014      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9015           (match_operand:SI 5 "gpc_reg_operand" "r"))
9016      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9017           (match_operand:SI 6 "gpc_reg_operand" "r"))
9018      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9019           (match_operand:SI 7 "gpc_reg_operand" "r"))
9020      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9021           (match_operand:SI 8 "gpc_reg_operand" "r"))
9022      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9023           (match_operand:SI 9 "gpc_reg_operand" "r"))
9024      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9025           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9026   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9027   "stswi %2,%1,%O0"
9028   [(set_attr "type" "store")
9029    (set_attr "update" "yes")
9030    (set_attr "indexed" "yes")
9031    (set_attr "cell_micro" "always")])
9033 (define_insn "*stmsi7"
9034   [(match_parallel 0 "store_multiple_operation"
9035     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9036           (match_operand:SI 2 "gpc_reg_operand" "r"))
9037      (clobber (match_scratch:SI 3 "=X"))
9038      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9039           (match_operand:SI 4 "gpc_reg_operand" "r"))
9040      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9041           (match_operand:SI 5 "gpc_reg_operand" "r"))
9042      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9043           (match_operand:SI 6 "gpc_reg_operand" "r"))
9044      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9045           (match_operand:SI 7 "gpc_reg_operand" "r"))
9046      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9047           (match_operand:SI 8 "gpc_reg_operand" "r"))
9048      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9049           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9050   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9051   "stswi %2,%1,%O0"
9052   [(set_attr "type" "store")
9053    (set_attr "update" "yes")
9054    (set_attr "indexed" "yes")
9055    (set_attr "cell_micro" "always")])
9057 (define_insn "*stmsi6"
9058   [(match_parallel 0 "store_multiple_operation"
9059     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9060           (match_operand:SI 2 "gpc_reg_operand" "r"))
9061      (clobber (match_scratch:SI 3 "=X"))
9062      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9063           (match_operand:SI 4 "gpc_reg_operand" "r"))
9064      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9065           (match_operand:SI 5 "gpc_reg_operand" "r"))
9066      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9067           (match_operand:SI 6 "gpc_reg_operand" "r"))
9068      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9069           (match_operand:SI 7 "gpc_reg_operand" "r"))
9070      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9071           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9072   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9073   "stswi %2,%1,%O0"
9074   [(set_attr "type" "store")
9075    (set_attr "update" "yes")
9076    (set_attr "indexed" "yes")
9077    (set_attr "cell_micro" "always")])
9079 (define_insn "*stmsi5"
9080   [(match_parallel 0 "store_multiple_operation"
9081     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9082           (match_operand:SI 2 "gpc_reg_operand" "r"))
9083      (clobber (match_scratch:SI 3 "=X"))
9084      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9085           (match_operand:SI 4 "gpc_reg_operand" "r"))
9086      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9087           (match_operand:SI 5 "gpc_reg_operand" "r"))
9088      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9089           (match_operand:SI 6 "gpc_reg_operand" "r"))
9090      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9091           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9092   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9093   "stswi %2,%1,%O0"
9094   [(set_attr "type" "store")
9095    (set_attr "update" "yes")
9096    (set_attr "indexed" "yes")
9097    (set_attr "cell_micro" "always")])
9099 (define_insn "*stmsi4"
9100   [(match_parallel 0 "store_multiple_operation"
9101     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9102           (match_operand:SI 2 "gpc_reg_operand" "r"))
9103      (clobber (match_scratch:SI 3 "=X"))
9104      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9105           (match_operand:SI 4 "gpc_reg_operand" "r"))
9106      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9107           (match_operand:SI 5 "gpc_reg_operand" "r"))
9108      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9109           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9110   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9111   "stswi %2,%1,%O0"
9112   [(set_attr "type" "store")
9113    (set_attr "update" "yes")
9114    (set_attr "indexed" "yes")
9115    (set_attr "cell_micro" "always")])
9117 (define_insn "*stmsi3"
9118   [(match_parallel 0 "store_multiple_operation"
9119     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9120           (match_operand:SI 2 "gpc_reg_operand" "r"))
9121      (clobber (match_scratch:SI 3 "=X"))
9122      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9123           (match_operand:SI 4 "gpc_reg_operand" "r"))
9124      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9125           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9126   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9127   "stswi %2,%1,%O0"
9128   [(set_attr "type" "store")
9129    (set_attr "update" "yes")
9130    (set_attr "indexed" "yes")
9131    (set_attr "cell_micro" "always")])
9133 (define_expand "setmemsi"
9134   [(parallel [(set (match_operand:BLK 0 "" "")
9135                    (match_operand 2 "const_int_operand" ""))
9136               (use (match_operand:SI 1 "" ""))
9137               (use (match_operand:SI 3 "" ""))])]
9138   ""
9139   "
9141   /* If value to set is not zero, use the library routine.  */
9142   if (operands[2] != const0_rtx)
9143     FAIL;
9145   if (expand_block_clear (operands))
9146     DONE;
9147   else
9148     FAIL;
9151 ;; String compare N insn.
9152 ;; Argument 0 is the target (result)
9153 ;; Argument 1 is the destination
9154 ;; Argument 2 is the source
9155 ;; Argument 3 is the length
9156 ;; Argument 4 is the alignment
9158 (define_expand "cmpstrnsi"
9159   [(parallel [(set (match_operand:SI 0)
9160                (compare:SI (match_operand:BLK 1)
9161                            (match_operand:BLK 2)))
9162               (use (match_operand:SI 3))
9163               (use (match_operand:SI 4))])]
9164   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9166   if (optimize_insn_for_size_p ())
9167     FAIL;
9169   if (expand_strn_compare (operands, 0))
9170     DONE;
9171   else  
9172     FAIL;
9175 ;; String compare insn.
9176 ;; Argument 0 is the target (result)
9177 ;; Argument 1 is the destination
9178 ;; Argument 2 is the source
9179 ;; Argument 3 is the alignment
9181 (define_expand "cmpstrsi"
9182   [(parallel [(set (match_operand:SI 0)
9183                (compare:SI (match_operand:BLK 1)
9184                            (match_operand:BLK 2)))
9185               (use (match_operand:SI 3))])]
9186   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9188   if (optimize_insn_for_size_p ())
9189     FAIL;
9191   if (expand_strn_compare (operands, 1))
9192     DONE;
9193   else  
9194     FAIL;
9197 ;; Block compare insn.
9198 ;; Argument 0 is the target (result)
9199 ;; Argument 1 is the destination
9200 ;; Argument 2 is the source
9201 ;; Argument 3 is the length
9202 ;; Argument 4 is the alignment
9204 (define_expand "cmpmemsi"
9205   [(parallel [(set (match_operand:SI 0)
9206                (compare:SI (match_operand:BLK 1)
9207                            (match_operand:BLK 2)))
9208               (use (match_operand:SI 3))
9209               (use (match_operand:SI 4))])]
9210   "TARGET_POPCNTD"
9212   if (expand_block_compare (operands))
9213     DONE;
9214   else
9215     FAIL;
9218 ;; String/block move insn.
9219 ;; Argument 0 is the destination
9220 ;; Argument 1 is the source
9221 ;; Argument 2 is the length
9222 ;; Argument 3 is the alignment
9224 (define_expand "movmemsi"
9225   [(parallel [(set (match_operand:BLK 0 "" "")
9226                    (match_operand:BLK 1 "" ""))
9227               (use (match_operand:SI 2 "" ""))
9228               (use (match_operand:SI 3 "" ""))])]
9229   ""
9230   "
9232   if (expand_block_move (operands))
9233     DONE;
9234   else
9235     FAIL;
9238 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9239 ;; register allocator doesn't have a clue about allocating 8 word registers.
9240 ;; rD/rS = r5 is preferred, efficient form.
9241 (define_expand "movmemsi_8reg"
9242   [(parallel [(set (match_operand 0 "" "")
9243                    (match_operand 1 "" ""))
9244               (use (match_operand 2 "" ""))
9245               (use (match_operand 3 "" ""))
9246               (clobber (reg:SI  5))
9247               (clobber (reg:SI  6))
9248               (clobber (reg:SI  7))
9249               (clobber (reg:SI  8))
9250               (clobber (reg:SI  9))
9251               (clobber (reg:SI 10))
9252               (clobber (reg:SI 11))
9253               (clobber (reg:SI 12))
9254               (clobber (match_scratch:SI 4 ""))])]
9255   "TARGET_STRING"
9256   "")
9258 (define_insn ""
9259   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9260         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9261    (use (match_operand:SI 2 "immediate_operand" "i"))
9262    (use (match_operand:SI 3 "immediate_operand" "i"))
9263    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9264    (clobber (reg:SI  6))
9265    (clobber (reg:SI  7))
9266    (clobber (reg:SI  8))
9267    (clobber (reg:SI  9))
9268    (clobber (reg:SI 10))
9269    (clobber (reg:SI 11))
9270    (clobber (reg:SI 12))
9271    (clobber (match_scratch:SI 5 "=X"))]
9272   "TARGET_STRING
9273    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9274        || INTVAL (operands[2]) == 0)
9275    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9276    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9277    && REGNO (operands[4]) == 5"
9278   "lswi %4,%1,%2\;stswi %4,%0,%2"
9279   [(set_attr "type" "store")
9280    (set_attr "update" "yes")
9281    (set_attr "indexed" "yes")
9282    (set_attr "cell_micro" "always")
9283    (set_attr "length" "8")])
9285 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9286 ;; register allocator doesn't have a clue about allocating 6 word registers.
9287 ;; rD/rS = r5 is preferred, efficient form.
9288 (define_expand "movmemsi_6reg"
9289   [(parallel [(set (match_operand 0 "" "")
9290                    (match_operand 1 "" ""))
9291               (use (match_operand 2 "" ""))
9292               (use (match_operand 3 "" ""))
9293               (clobber (reg:SI  5))
9294               (clobber (reg:SI  6))
9295               (clobber (reg:SI  7))
9296               (clobber (reg:SI  8))
9297               (clobber (reg:SI  9))
9298               (clobber (reg:SI 10))
9299               (clobber (match_scratch:SI 4 ""))])]
9300   "TARGET_STRING"
9301   "")
9303 (define_insn ""
9304   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9305         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9306    (use (match_operand:SI 2 "immediate_operand" "i"))
9307    (use (match_operand:SI 3 "immediate_operand" "i"))
9308    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9309    (clobber (reg:SI  6))
9310    (clobber (reg:SI  7))
9311    (clobber (reg:SI  8))
9312    (clobber (reg:SI  9))
9313    (clobber (reg:SI 10))
9314    (clobber (match_scratch:SI 5 "=X"))]
9315   "TARGET_STRING
9316    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9317    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9318    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9319    && REGNO (operands[4]) == 5"
9320   "lswi %4,%1,%2\;stswi %4,%0,%2"
9321   [(set_attr "type" "store")
9322    (set_attr "update" "yes")
9323    (set_attr "indexed" "yes")
9324    (set_attr "cell_micro" "always")
9325    (set_attr "length" "8")])
9327 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9328 ;; problems with TImode.
9329 ;; rD/rS = r5 is preferred, efficient form.
9330 (define_expand "movmemsi_4reg"
9331   [(parallel [(set (match_operand 0 "" "")
9332                    (match_operand 1 "" ""))
9333               (use (match_operand 2 "" ""))
9334               (use (match_operand 3 "" ""))
9335               (clobber (reg:SI 5))
9336               (clobber (reg:SI 6))
9337               (clobber (reg:SI 7))
9338               (clobber (reg:SI 8))
9339               (clobber (match_scratch:SI 4 ""))])]
9340   "TARGET_STRING"
9341   "")
9343 (define_insn ""
9344   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9345         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9346    (use (match_operand:SI 2 "immediate_operand" "i"))
9347    (use (match_operand:SI 3 "immediate_operand" "i"))
9348    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9349    (clobber (reg:SI 6))
9350    (clobber (reg:SI 7))
9351    (clobber (reg:SI 8))
9352    (clobber (match_scratch:SI 5 "=X"))]
9353   "TARGET_STRING
9354    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9355    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9356    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9357    && REGNO (operands[4]) == 5"
9358   "lswi %4,%1,%2\;stswi %4,%0,%2"
9359   [(set_attr "type" "store")
9360    (set_attr "update" "yes")
9361    (set_attr "indexed" "yes")
9362    (set_attr "cell_micro" "always")
9363    (set_attr "length" "8")])
9365 ;; Move up to 8 bytes at a time.
9366 (define_expand "movmemsi_2reg"
9367   [(parallel [(set (match_operand 0 "" "")
9368                    (match_operand 1 "" ""))
9369               (use (match_operand 2 "" ""))
9370               (use (match_operand 3 "" ""))
9371               (clobber (match_scratch:DI 4 ""))
9372               (clobber (match_scratch:SI 5 ""))])]
9373   "TARGET_STRING && ! TARGET_POWERPC64"
9374   "")
9376 (define_insn ""
9377   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9378         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9379    (use (match_operand:SI 2 "immediate_operand" "i"))
9380    (use (match_operand:SI 3 "immediate_operand" "i"))
9381    (clobber (match_scratch:DI 4 "=&r"))
9382    (clobber (match_scratch:SI 5 "=X"))]
9383   "TARGET_STRING && ! TARGET_POWERPC64
9384    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9385   "lswi %4,%1,%2\;stswi %4,%0,%2"
9386   [(set_attr "type" "store")
9387    (set_attr "update" "yes")
9388    (set_attr "indexed" "yes")
9389    (set_attr "cell_micro" "always")
9390    (set_attr "length" "8")])
9392 ;; Move up to 4 bytes at a time.
9393 (define_expand "movmemsi_1reg"
9394   [(parallel [(set (match_operand 0 "" "")
9395                    (match_operand 1 "" ""))
9396               (use (match_operand 2 "" ""))
9397               (use (match_operand 3 "" ""))
9398               (clobber (match_scratch:SI 4 ""))
9399               (clobber (match_scratch:SI 5 ""))])]
9400   "TARGET_STRING"
9401   "")
9403 (define_insn ""
9404   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9405         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9406    (use (match_operand:SI 2 "immediate_operand" "i"))
9407    (use (match_operand:SI 3 "immediate_operand" "i"))
9408    (clobber (match_scratch:SI 4 "=&r"))
9409    (clobber (match_scratch:SI 5 "=X"))]
9410   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9411   "lswi %4,%1,%2\;stswi %4,%0,%2"
9412   [(set_attr "type" "store")
9413    (set_attr "update" "yes")
9414    (set_attr "indexed" "yes")
9415    (set_attr "cell_micro" "always")
9416    (set_attr "length" "8")])
9418 ;; Define insns that do load or store with update.  Some of these we can
9419 ;; get by using pre-decrement or pre-increment, but the hardware can also
9420 ;; do cases where the increment is not the size of the object.
9422 ;; In all these cases, we use operands 0 and 1 for the register being
9423 ;; incremented because those are the operands that local-alloc will
9424 ;; tie and these are the pair most likely to be tieable (and the ones
9425 ;; that will benefit the most).
9427 (define_insn "*movdi_update1"
9428   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9429         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9430                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9431    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9432         (plus:DI (match_dup 1) (match_dup 2)))]
9433   "TARGET_POWERPC64 && TARGET_UPDATE
9434    && (!avoiding_indexed_address_p (DImode)
9435        || !gpc_reg_operand (operands[2], DImode))"
9436   "@
9437    ldux %3,%0,%2
9438    ldu %3,%2(%0)"
9439   [(set_attr "type" "load")
9440    (set_attr "update" "yes")
9441    (set_attr "indexed" "yes,no")])
9443 (define_insn "movdi_<mode>_update"
9444   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9445                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9446         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9447    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9448         (plus:P (match_dup 1) (match_dup 2)))]
9449   "TARGET_POWERPC64 && TARGET_UPDATE
9450    && (!avoiding_indexed_address_p (Pmode)
9451        || !gpc_reg_operand (operands[2], Pmode)
9452        || (REG_P (operands[0])
9453            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9454   "@
9455    stdux %3,%0,%2
9456    stdu %3,%2(%0)"
9457   [(set_attr "type" "store")
9458    (set_attr "update" "yes")
9459    (set_attr "indexed" "yes,no")])
9461 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9462 ;; needed for stack allocation, even if the user passes -mno-update.
9463 (define_insn "movdi_<mode>_update_stack"
9464   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9465                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9466         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9467    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9468         (plus:P (match_dup 1) (match_dup 2)))]
9469   "TARGET_POWERPC64"
9470   "@
9471    stdux %3,%0,%2
9472    stdu %3,%2(%0)"
9473   [(set_attr "type" "store")
9474    (set_attr "update" "yes")
9475    (set_attr "indexed" "yes,no")])
9477 (define_insn "*movsi_update1"
9478   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9479         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9480                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9481    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9482         (plus:SI (match_dup 1) (match_dup 2)))]
9483   "TARGET_UPDATE
9484    && (!avoiding_indexed_address_p (SImode)
9485        || !gpc_reg_operand (operands[2], SImode))"
9486   "@
9487    lwzux %3,%0,%2
9488    lwzu %3,%2(%0)"
9489   [(set_attr "type" "load")
9490    (set_attr "update" "yes")
9491    (set_attr "indexed" "yes,no")])
9493 (define_insn "*movsi_update2"
9494   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9495         (sign_extend:DI
9496          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9497                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9498    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9499         (plus:DI (match_dup 1) (match_dup 2)))]
9500   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9501    && !avoiding_indexed_address_p (DImode)"
9502   "lwaux %3,%0,%2"
9503   [(set_attr "type" "load")
9504    (set_attr "sign_extend" "yes")
9505    (set_attr "update" "yes")
9506    (set_attr "indexed" "yes")])
9508 (define_insn "movsi_update"
9509   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9510                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9511         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9512    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9513         (plus:SI (match_dup 1) (match_dup 2)))]
9514   "TARGET_UPDATE
9515    && (!avoiding_indexed_address_p (SImode)
9516        || !gpc_reg_operand (operands[2], SImode)
9517        || (REG_P (operands[0])
9518            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9519   "@
9520    stwux %3,%0,%2
9521    stwu %3,%2(%0)"
9522   [(set_attr "type" "store")
9523    (set_attr "update" "yes")
9524    (set_attr "indexed" "yes,no")])
9526 ;; This is an unconditional pattern; needed for stack allocation, even
9527 ;; if the user passes -mno-update.
9528 (define_insn "movsi_update_stack"
9529   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9530                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9531         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9532    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9533         (plus:SI (match_dup 1) (match_dup 2)))]
9534   ""
9535   "@
9536    stwux %3,%0,%2
9537    stwu %3,%2(%0)"
9538   [(set_attr "type" "store")
9539    (set_attr "update" "yes")
9540    (set_attr "indexed" "yes,no")])
9542 (define_insn "*movhi_update1"
9543   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9544         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9545                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9546    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9547         (plus:SI (match_dup 1) (match_dup 2)))]
9548   "TARGET_UPDATE
9549    && (!avoiding_indexed_address_p (SImode)
9550        || !gpc_reg_operand (operands[2], SImode))"
9551   "@
9552    lhzux %3,%0,%2
9553    lhzu %3,%2(%0)"
9554   [(set_attr "type" "load")
9555    (set_attr "update" "yes")
9556    (set_attr "indexed" "yes,no")])
9558 (define_insn "*movhi_update2"
9559   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9560         (zero_extend:SI
9561          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9562                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9563    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9564         (plus:SI (match_dup 1) (match_dup 2)))]
9565   "TARGET_UPDATE
9566    && (!avoiding_indexed_address_p (SImode)
9567        || !gpc_reg_operand (operands[2], SImode))"
9568   "@
9569    lhzux %3,%0,%2
9570    lhzu %3,%2(%0)"
9571   [(set_attr "type" "load")
9572    (set_attr "update" "yes")
9573    (set_attr "indexed" "yes,no")])
9575 (define_insn "*movhi_update3"
9576   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9577         (sign_extend:SI
9578          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9579                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9580    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9581         (plus:SI (match_dup 1) (match_dup 2)))]
9582   "TARGET_UPDATE && rs6000_gen_cell_microcode
9583    && (!avoiding_indexed_address_p (SImode)
9584        || !gpc_reg_operand (operands[2], SImode))"
9585   "@
9586    lhaux %3,%0,%2
9587    lhau %3,%2(%0)"
9588   [(set_attr "type" "load")
9589    (set_attr "sign_extend" "yes")
9590    (set_attr "update" "yes")
9591    (set_attr "indexed" "yes,no")])
9593 (define_insn "*movhi_update4"
9594   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9595                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9596         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9597    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9598         (plus:SI (match_dup 1) (match_dup 2)))]
9599   "TARGET_UPDATE
9600    && (!avoiding_indexed_address_p (SImode)
9601        || !gpc_reg_operand (operands[2], SImode))"
9602   "@
9603    sthux %3,%0,%2
9604    sthu %3,%2(%0)"
9605   [(set_attr "type" "store")
9606    (set_attr "update" "yes")
9607    (set_attr "indexed" "yes,no")])
9609 (define_insn "*movqi_update1"
9610   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9611         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9612                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9613    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9614         (plus:SI (match_dup 1) (match_dup 2)))]
9615   "TARGET_UPDATE
9616    && (!avoiding_indexed_address_p (SImode)
9617        || !gpc_reg_operand (operands[2], SImode))"
9618   "@
9619    lbzux %3,%0,%2
9620    lbzu %3,%2(%0)"
9621   [(set_attr "type" "load")
9622    (set_attr "update" "yes")
9623    (set_attr "indexed" "yes,no")])
9625 (define_insn "*movqi_update2"
9626   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9627         (zero_extend:SI
9628          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9629                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9630    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9631         (plus:SI (match_dup 1) (match_dup 2)))]
9632   "TARGET_UPDATE
9633    && (!avoiding_indexed_address_p (SImode)
9634        || !gpc_reg_operand (operands[2], SImode))"
9635   "@
9636    lbzux %3,%0,%2
9637    lbzu %3,%2(%0)"
9638   [(set_attr "type" "load")
9639    (set_attr "update" "yes")
9640    (set_attr "indexed" "yes,no")])
9642 (define_insn "*movqi_update3"
9643   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9644                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9645         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9646    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9647         (plus:SI (match_dup 1) (match_dup 2)))]
9648   "TARGET_UPDATE
9649    && (!avoiding_indexed_address_p (SImode)
9650        || !gpc_reg_operand (operands[2], SImode))"
9651   "@
9652    stbux %3,%0,%2
9653    stbu %3,%2(%0)"
9654   [(set_attr "type" "store")
9655    (set_attr "update" "yes")
9656    (set_attr "indexed" "yes,no")])
9658 (define_insn "*movsf_update1"
9659   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9660         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9661                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9662    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9663         (plus:SI (match_dup 1) (match_dup 2)))]
9664   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9665    && (!avoiding_indexed_address_p (SImode)
9666        || !gpc_reg_operand (operands[2], SImode))"
9667   "@
9668    lfsux %3,%0,%2
9669    lfsu %3,%2(%0)"
9670   [(set_attr "type" "fpload")
9671    (set_attr "update" "yes")
9672    (set_attr "indexed" "yes,no")])
9674 (define_insn "*movsf_update2"
9675   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9676                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9677         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9678    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9679         (plus:SI (match_dup 1) (match_dup 2)))]
9680   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9681    && (!avoiding_indexed_address_p (SImode)
9682        || !gpc_reg_operand (operands[2], SImode))"
9683   "@
9684    stfsux %3,%0,%2
9685    stfsu %3,%2(%0)"
9686   [(set_attr "type" "fpstore")
9687    (set_attr "update" "yes")
9688    (set_attr "indexed" "yes,no")])
9690 (define_insn "*movsf_update3"
9691   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9692         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9693                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9694    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9695         (plus:SI (match_dup 1) (match_dup 2)))]
9696   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9697    && (!avoiding_indexed_address_p (SImode)
9698        || !gpc_reg_operand (operands[2], SImode))"
9699   "@
9700    lwzux %3,%0,%2
9701    lwzu %3,%2(%0)"
9702   [(set_attr "type" "load")
9703    (set_attr "update" "yes")
9704    (set_attr "indexed" "yes,no")])
9706 (define_insn "*movsf_update4"
9707   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9708                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9709         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9710    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9711         (plus:SI (match_dup 1) (match_dup 2)))]
9712   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9713    && (!avoiding_indexed_address_p (SImode)
9714        || !gpc_reg_operand (operands[2], SImode))"
9715   "@
9716    stwux %3,%0,%2
9717    stwu %3,%2(%0)"
9718   [(set_attr "type" "store")
9719    (set_attr "update" "yes")
9720    (set_attr "indexed" "yes,no")])
9722 (define_insn "*movdf_update1"
9723   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9724         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9725                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9726    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9727         (plus:SI (match_dup 1) (match_dup 2)))]
9728   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9729    && (!avoiding_indexed_address_p (SImode)
9730        || !gpc_reg_operand (operands[2], SImode))"
9731   "@
9732    lfdux %3,%0,%2
9733    lfdu %3,%2(%0)"
9734   [(set_attr "type" "fpload")
9735    (set_attr "update" "yes")
9736    (set_attr "indexed" "yes,no")
9737    (set_attr "size" "64")])
9739 (define_insn "*movdf_update2"
9740   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9741                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9742         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9743    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9744         (plus:SI (match_dup 1) (match_dup 2)))]
9745   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9746    && (!avoiding_indexed_address_p (SImode)
9747        || !gpc_reg_operand (operands[2], SImode))"
9748   "@
9749    stfdux %3,%0,%2
9750    stfdu %3,%2(%0)"
9751   [(set_attr "type" "fpstore")
9752    (set_attr "update" "yes")
9753    (set_attr "indexed" "yes,no")])
9756 ;; After inserting conditional returns we can sometimes have
9757 ;; unnecessary register moves.  Unfortunately we cannot have a
9758 ;; modeless peephole here, because some single SImode sets have early
9759 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9760 ;; sequences, using get_attr_length here will smash the operands
9761 ;; array.  Neither is there an early_cobbler_p predicate.
9762 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9763 ;; Also this optimization interferes with scalars going into
9764 ;; altivec registers (the code does reloading through the FPRs).
9765 (define_peephole2
9766   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9767         (match_operand:DF 1 "any_operand" ""))
9768    (set (match_operand:DF 2 "gpc_reg_operand" "")
9769         (match_dup 0))]
9770   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9771    && !TARGET_UPPER_REGS_DF
9772    && peep2_reg_dead_p (2, operands[0])"
9773   [(set (match_dup 2) (match_dup 1))])
9775 (define_peephole2
9776   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9777         (match_operand:SF 1 "any_operand" ""))
9778    (set (match_operand:SF 2 "gpc_reg_operand" "")
9779         (match_dup 0))]
9780   "!TARGET_UPPER_REGS_SF
9781    && peep2_reg_dead_p (2, operands[0])"
9782   [(set (match_dup 2) (match_dup 1))])
9785 ;; TLS support.
9787 ;; Mode attributes for different ABIs.
9788 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9789 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9790 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9791 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9793 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9794   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9795         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9796               (match_operand 4 "" "g")))
9797    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9798                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9799                    UNSPEC_TLSGD)
9800    (clobber (reg:SI LR_REGNO))]
9801   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9803   if (TARGET_CMODEL != CMODEL_SMALL)
9804     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9805            "bl %z3\;nop";
9806   else
9807     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9809   "&& TARGET_TLS_MARKERS"
9810   [(set (match_dup 0)
9811         (unspec:TLSmode [(match_dup 1)
9812                          (match_dup 2)]
9813                         UNSPEC_TLSGD))
9814    (parallel [(set (match_dup 0)
9815                    (call (mem:TLSmode (match_dup 3))
9816                          (match_dup 4)))
9817               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9818               (clobber (reg:SI LR_REGNO))])]
9819   ""
9820   [(set_attr "type" "two")
9821    (set (attr "length")
9822      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9823                    (const_int 16)
9824                    (const_int 12)))])
9826 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9827   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9828         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9829               (match_operand 4 "" "g")))
9830    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9831                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9832                    UNSPEC_TLSGD)
9833    (clobber (reg:SI LR_REGNO))]
9834   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9836   if (flag_pic)
9837     {
9838       if (TARGET_SECURE_PLT && flag_pic == 2)
9839         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9840       else
9841         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9842     }
9843   else
9844     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9846   "&& TARGET_TLS_MARKERS"
9847   [(set (match_dup 0)
9848         (unspec:TLSmode [(match_dup 1)
9849                          (match_dup 2)]
9850                         UNSPEC_TLSGD))
9851    (parallel [(set (match_dup 0)
9852                    (call (mem:TLSmode (match_dup 3))
9853                          (match_dup 4)))
9854               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9855               (clobber (reg:SI LR_REGNO))])]
9856   ""
9857   [(set_attr "type" "two")
9858    (set_attr "length" "8")])
9860 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9861   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9862         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9863                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9864                         UNSPEC_TLSGD))]
9865   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9866   "addi %0,%1,%2@got@tlsgd"
9867   "&& TARGET_CMODEL != CMODEL_SMALL"
9868   [(set (match_dup 3)
9869         (high:TLSmode
9870             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9871    (set (match_dup 0)
9872         (lo_sum:TLSmode (match_dup 3)
9873             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9874   "
9876   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9878   [(set (attr "length")
9879      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9880                    (const_int 8)
9881                    (const_int 4)))])
9883 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9884   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9885      (high:TLSmode
9886        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9887                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9888                        UNSPEC_TLSGD)))]
9889   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9890   "addis %0,%1,%2@got@tlsgd@ha"
9891   [(set_attr "length" "4")])
9893 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9894   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9895      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9896        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9897                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9898                        UNSPEC_TLSGD)))]
9899   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9900   "addi %0,%1,%2@got@tlsgd@l"
9901   [(set_attr "length" "4")])
9903 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9904   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9905         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9906               (match_operand 2 "" "g")))
9907    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9908                    UNSPEC_TLSGD)
9909    (clobber (reg:SI LR_REGNO))]
9910   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9911    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9912   "bl %z1(%3@tlsgd)\;nop"
9913   [(set_attr "type" "branch")
9914    (set_attr "length" "8")])
9916 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9917   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9918         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9919               (match_operand 2 "" "g")))
9920    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9921                    UNSPEC_TLSGD)
9922    (clobber (reg:SI LR_REGNO))]
9923   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9925   if (flag_pic)
9926     {
9927       if (TARGET_SECURE_PLT && flag_pic == 2)
9928         return "bl %z1+32768(%3@tlsgd)@plt";
9929       return "bl %z1(%3@tlsgd)@plt";
9930     }
9931   return "bl %z1(%3@tlsgd)";
9933   [(set_attr "type" "branch")
9934    (set_attr "length" "4")])
9936 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9937   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9938         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9939               (match_operand 3 "" "g")))
9940    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9941                    UNSPEC_TLSLD)
9942    (clobber (reg:SI LR_REGNO))]
9943   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9945   if (TARGET_CMODEL != CMODEL_SMALL)
9946     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9947            "bl %z2\;nop";
9948   else
9949     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9951   "&& TARGET_TLS_MARKERS"
9952   [(set (match_dup 0)
9953         (unspec:TLSmode [(match_dup 1)]
9954                         UNSPEC_TLSLD))
9955    (parallel [(set (match_dup 0)
9956                    (call (mem:TLSmode (match_dup 2))
9957                          (match_dup 3)))
9958               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9959               (clobber (reg:SI LR_REGNO))])]
9960   ""
9961   [(set_attr "type" "two")
9962    (set (attr "length")
9963      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9964                    (const_int 16)
9965                    (const_int 12)))])
9967 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9968   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9969         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9970               (match_operand 3 "" "g")))
9971    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9972                    UNSPEC_TLSLD)
9973    (clobber (reg:SI LR_REGNO))]
9974   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9976   if (flag_pic)
9977     {
9978       if (TARGET_SECURE_PLT && flag_pic == 2)
9979         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9980       else
9981         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9982     }
9983   else
9984     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9986   "&& TARGET_TLS_MARKERS"
9987   [(set (match_dup 0)
9988         (unspec:TLSmode [(match_dup 1)]
9989                         UNSPEC_TLSLD))
9990    (parallel [(set (match_dup 0)
9991                    (call (mem:TLSmode (match_dup 2))
9992                          (match_dup 3)))
9993               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9994               (clobber (reg:SI LR_REGNO))])]
9995   ""
9996   [(set_attr "length" "8")])
9998 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9999   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10000         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10001                         UNSPEC_TLSLD))]
10002   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10003   "addi %0,%1,%&@got@tlsld"
10004   "&& TARGET_CMODEL != CMODEL_SMALL"
10005   [(set (match_dup 2)
10006         (high:TLSmode
10007             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10008    (set (match_dup 0)
10009         (lo_sum:TLSmode (match_dup 2)
10010             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10011   "
10013   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10015   [(set (attr "length")
10016      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10017                    (const_int 8)
10018                    (const_int 4)))])
10020 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10021   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10022      (high:TLSmode
10023        (unspec:TLSmode [(const_int 0)
10024                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10025                        UNSPEC_TLSLD)))]
10026   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10027   "addis %0,%1,%&@got@tlsld@ha"
10028   [(set_attr "length" "4")])
10030 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10031   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10032      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10033        (unspec:TLSmode [(const_int 0)
10034                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10035                        UNSPEC_TLSLD)))]
10036   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10037   "addi %0,%1,%&@got@tlsld@l"
10038   [(set_attr "length" "4")])
10040 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10041   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10042         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10043               (match_operand 2 "" "g")))
10044    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10045    (clobber (reg:SI LR_REGNO))]
10046   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10047    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10048   "bl %z1(%&@tlsld)\;nop"
10049   [(set_attr "type" "branch")
10050    (set_attr "length" "8")])
10052 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10053   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10054         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10055               (match_operand 2 "" "g")))
10056    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10057    (clobber (reg:SI LR_REGNO))]
10058   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10060   if (flag_pic)
10061     {
10062       if (TARGET_SECURE_PLT && flag_pic == 2)
10063         return "bl %z1+32768(%&@tlsld)@plt";
10064       return "bl %z1(%&@tlsld)@plt";
10065     }
10066   return "bl %z1(%&@tlsld)";
10068   [(set_attr "type" "branch")
10069    (set_attr "length" "4")])
10071 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10072   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10073         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10074                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10075                         UNSPEC_TLSDTPREL))]
10076   "HAVE_AS_TLS"
10077   "addi %0,%1,%2@dtprel")
10079 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10080   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10081         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10082                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10083                         UNSPEC_TLSDTPRELHA))]
10084   "HAVE_AS_TLS"
10085   "addis %0,%1,%2@dtprel@ha")
10087 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10088   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10089         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10090                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10091                         UNSPEC_TLSDTPRELLO))]
10092   "HAVE_AS_TLS"
10093   "addi %0,%1,%2@dtprel@l")
10095 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10096   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10097         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10098                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10099                         UNSPEC_TLSGOTDTPREL))]
10100   "HAVE_AS_TLS"
10101   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10102   "&& TARGET_CMODEL != CMODEL_SMALL"
10103   [(set (match_dup 3)
10104         (high:TLSmode
10105             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10106    (set (match_dup 0)
10107         (lo_sum:TLSmode (match_dup 3)
10108             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10109   "
10111   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10113   [(set (attr "length")
10114      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10115                    (const_int 8)
10116                    (const_int 4)))])
10118 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10119   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10120      (high:TLSmode
10121        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10122                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10123                        UNSPEC_TLSGOTDTPREL)))]
10124   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10125   "addis %0,%1,%2@got@dtprel@ha"
10126   [(set_attr "length" "4")])
10128 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10129   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10130      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10131          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10132                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10133                          UNSPEC_TLSGOTDTPREL)))]
10134   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10135   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10136   [(set_attr "length" "4")])
10138 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10139   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10140         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10141                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10142                         UNSPEC_TLSTPREL))]
10143   "HAVE_AS_TLS"
10144   "addi %0,%1,%2@tprel")
10146 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10147   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10148         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10149                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10150                         UNSPEC_TLSTPRELHA))]
10151   "HAVE_AS_TLS"
10152   "addis %0,%1,%2@tprel@ha")
10154 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10155   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10156         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10157                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10158                         UNSPEC_TLSTPRELLO))]
10159   "HAVE_AS_TLS"
10160   "addi %0,%1,%2@tprel@l")
10162 ;; "b" output constraint here and on tls_tls input to support linker tls
10163 ;; optimization.  The linker may edit the instructions emitted by a
10164 ;; tls_got_tprel/tls_tls pair to addis,addi.
10165 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10166   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10167         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10168                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10169                         UNSPEC_TLSGOTTPREL))]
10170   "HAVE_AS_TLS"
10171   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10172   "&& TARGET_CMODEL != CMODEL_SMALL"
10173   [(set (match_dup 3)
10174         (high:TLSmode
10175             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10176    (set (match_dup 0)
10177         (lo_sum:TLSmode (match_dup 3)
10178             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10179   "
10181   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10183   [(set (attr "length")
10184      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10185                    (const_int 8)
10186                    (const_int 4)))])
10188 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10189   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10190      (high:TLSmode
10191        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10192                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10193                        UNSPEC_TLSGOTTPREL)))]
10194   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10195   "addis %0,%1,%2@got@tprel@ha"
10196   [(set_attr "length" "4")])
10198 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10199   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10200      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10201          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10202                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10203                          UNSPEC_TLSGOTTPREL)))]
10204   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10205   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10206   [(set_attr "length" "4")])
10208 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10209   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10210         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10211                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10212                         UNSPEC_TLSTLS))]
10213   "TARGET_ELF && HAVE_AS_TLS"
10214   "add %0,%1,%2@tls")
10216 (define_expand "tls_get_tpointer"
10217   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10218         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10219   "TARGET_XCOFF && HAVE_AS_TLS"
10220   "
10222   emit_insn (gen_tls_get_tpointer_internal ());
10223   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10224   DONE;
10227 (define_insn "tls_get_tpointer_internal"
10228   [(set (reg:SI 3)
10229         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10230    (clobber (reg:SI LR_REGNO))]
10231   "TARGET_XCOFF && HAVE_AS_TLS"
10232   "bla __get_tpointer")
10234 (define_expand "tls_get_addr<mode>"
10235   [(set (match_operand:P 0 "gpc_reg_operand" "")
10236         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10237                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10238   "TARGET_XCOFF && HAVE_AS_TLS"
10239   "
10241   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10242   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10243   emit_insn (gen_tls_get_addr_internal<mode> ());
10244   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10245   DONE;
10248 (define_insn "tls_get_addr_internal<mode>"
10249   [(set (reg:P 3)
10250         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10251    (clobber (reg:P 0))
10252    (clobber (reg:P 4))
10253    (clobber (reg:P 5))
10254    (clobber (reg:P 11))
10255    (clobber (reg:CC CR0_REGNO))
10256    (clobber (reg:P LR_REGNO))]
10257   "TARGET_XCOFF && HAVE_AS_TLS"
10258   "bla __tls_get_addr")
10260 ;; Next come insns related to the calling sequence.
10262 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10263 ;; We move the back-chain and decrement the stack pointer.
10265 (define_expand "allocate_stack"
10266   [(set (match_operand 0 "gpc_reg_operand" "")
10267         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10268    (set (reg 1)
10269         (minus (reg 1) (match_dup 1)))]
10270   ""
10271   "
10272 { rtx chain = gen_reg_rtx (Pmode);
10273   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10274   rtx neg_op0;
10275   rtx insn, par, set, mem;
10277   emit_move_insn (chain, stack_bot);
10279   /* Check stack bounds if necessary.  */
10280   if (crtl->limit_stack)
10281     {
10282       rtx available;
10283       available = expand_binop (Pmode, sub_optab,
10284                                 stack_pointer_rtx, stack_limit_rtx,
10285                                 NULL_RTX, 1, OPTAB_WIDEN);
10286       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10287     }
10289   if (GET_CODE (operands[1]) != CONST_INT
10290       || INTVAL (operands[1]) < -32767
10291       || INTVAL (operands[1]) > 32768)
10292     {
10293       neg_op0 = gen_reg_rtx (Pmode);
10294       if (TARGET_32BIT)
10295         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10296       else
10297         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10298     }
10299   else
10300     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10302   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10303                                        : gen_movdi_di_update_stack))
10304                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10305                          chain));
10306   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10307      it now and set the alias set/attributes. The above gen_*_update
10308      calls will generate a PARALLEL with the MEM set being the first
10309      operation. */
10310   par = PATTERN (insn);
10311   gcc_assert (GET_CODE (par) == PARALLEL);
10312   set = XVECEXP (par, 0, 0);
10313   gcc_assert (GET_CODE (set) == SET);
10314   mem = SET_DEST (set);
10315   gcc_assert (MEM_P (mem));
10316   MEM_NOTRAP_P (mem) = 1;
10317   set_mem_alias_set (mem, get_frame_alias_set ());
10319   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10320   DONE;
10323 ;; These patterns say how to save and restore the stack pointer.  We need not
10324 ;; save the stack pointer at function level since we are careful to
10325 ;; preserve the backchain.  At block level, we have to restore the backchain
10326 ;; when we restore the stack pointer.
10328 ;; For nonlocal gotos, we must save both the stack pointer and its
10329 ;; backchain and restore both.  Note that in the nonlocal case, the
10330 ;; save area is a memory location.
10332 (define_expand "save_stack_function"
10333   [(match_operand 0 "any_operand" "")
10334    (match_operand 1 "any_operand" "")]
10335   ""
10336   "DONE;")
10338 (define_expand "restore_stack_function"
10339   [(match_operand 0 "any_operand" "")
10340    (match_operand 1 "any_operand" "")]
10341   ""
10342   "DONE;")
10344 ;; Adjust stack pointer (op0) to a new value (op1).
10345 ;; First copy old stack backchain to new location, and ensure that the
10346 ;; scheduler won't reorder the sp assignment before the backchain write.
10347 (define_expand "restore_stack_block"
10348   [(set (match_dup 2) (match_dup 3))
10349    (set (match_dup 4) (match_dup 2))
10350    (match_dup 5)
10351    (set (match_operand 0 "register_operand" "")
10352         (match_operand 1 "register_operand" ""))]
10353   ""
10354   "
10356   rtvec p;
10358   operands[1] = force_reg (Pmode, operands[1]);
10359   operands[2] = gen_reg_rtx (Pmode);
10360   operands[3] = gen_frame_mem (Pmode, operands[0]);
10361   operands[4] = gen_frame_mem (Pmode, operands[1]);
10362   p = rtvec_alloc (1);
10363   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10364                                   const0_rtx);
10365   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10368 (define_expand "save_stack_nonlocal"
10369   [(set (match_dup 3) (match_dup 4))
10370    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10371    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10372   ""
10373   "
10375   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10377   /* Copy the backchain to the first word, sp to the second.  */
10378   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10379   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10380   operands[3] = gen_reg_rtx (Pmode);
10381   operands[4] = gen_frame_mem (Pmode, operands[1]);
10384 (define_expand "restore_stack_nonlocal"
10385   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10386    (set (match_dup 3) (match_dup 4))
10387    (set (match_dup 5) (match_dup 2))
10388    (match_dup 6)
10389    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10390   ""
10391   "
10393   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10394   rtvec p;
10396   /* Restore the backchain from the first word, sp from the second.  */
10397   operands[2] = gen_reg_rtx (Pmode);
10398   operands[3] = gen_reg_rtx (Pmode);
10399   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10400   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10401   operands[5] = gen_frame_mem (Pmode, operands[3]);
10402   p = rtvec_alloc (1);
10403   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10404                                   const0_rtx);
10405   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10408 ;; TOC register handling.
10410 ;; Code to initialize the TOC register...
10412 (define_insn "load_toc_aix_si"
10413   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10414                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10415               (use (reg:SI 2))])]
10416   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10417   "*
10419   char buf[30];
10420   extern int need_toc_init;
10421   need_toc_init = 1;
10422   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10423   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10424   operands[2] = gen_rtx_REG (Pmode, 2);
10425   return \"lwz %0,%1(%2)\";
10427   [(set_attr "type" "load")
10428    (set_attr "update" "no")
10429    (set_attr "indexed" "no")])
10431 (define_insn "load_toc_aix_di"
10432   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10433                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10434               (use (reg:DI 2))])]
10435   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10436   "*
10438   char buf[30];
10439   extern int need_toc_init;
10440   need_toc_init = 1;
10441   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10442                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10443   if (TARGET_ELF)
10444     strcat (buf, \"@toc\");
10445   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10446   operands[2] = gen_rtx_REG (Pmode, 2);
10447   return \"ld %0,%1(%2)\";
10449   [(set_attr "type" "load")
10450    (set_attr "update" "no")
10451    (set_attr "indexed" "no")])
10453 (define_insn "load_toc_v4_pic_si"
10454   [(set (reg:SI LR_REGNO)
10455         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10456   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10457   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10458   [(set_attr "type" "branch")
10459    (set_attr "length" "4")])
10461 (define_expand "load_toc_v4_PIC_1"
10462   [(parallel [(set (reg:SI LR_REGNO)
10463                    (match_operand:SI 0 "immediate_operand" "s"))
10464               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10465   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10466    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10467   "")
10469 (define_insn "load_toc_v4_PIC_1_normal"
10470   [(set (reg:SI LR_REGNO)
10471         (match_operand:SI 0 "immediate_operand" "s"))
10472    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10473   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10474    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10475   "bcl 20,31,%0\\n%0:"
10476   [(set_attr "type" "branch")
10477    (set_attr "length" "4")
10478    (set_attr "cannot_copy" "yes")])
10480 (define_insn "load_toc_v4_PIC_1_476"
10481   [(set (reg:SI LR_REGNO)
10482         (match_operand:SI 0 "immediate_operand" "s"))
10483    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10484   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10485    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10486   "*
10488   char name[32];
10489   static char templ[32];
10491   get_ppc476_thunk_name (name);
10492   sprintf (templ, \"bl %s\\n%%0:\", name);
10493   return templ;
10495   [(set_attr "type" "branch")
10496    (set_attr "length" "4")
10497    (set_attr "cannot_copy" "yes")])
10499 (define_expand "load_toc_v4_PIC_1b"
10500   [(parallel [(set (reg:SI LR_REGNO)
10501                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10502                                (label_ref (match_operand 1 "" ""))]
10503                            UNSPEC_TOCPTR))
10504               (match_dup 1)])]
10505   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10506   "")
10508 (define_insn "load_toc_v4_PIC_1b_normal"
10509   [(set (reg:SI LR_REGNO)
10510         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10511                     (label_ref (match_operand 1 "" ""))]
10512                 UNSPEC_TOCPTR))
10513    (match_dup 1)]
10514   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10515   "bcl 20,31,$+8\;.long %0-$"
10516   [(set_attr "type" "branch")
10517    (set_attr "length" "8")])
10519 (define_insn "load_toc_v4_PIC_1b_476"
10520   [(set (reg:SI LR_REGNO)
10521         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10522                     (label_ref (match_operand 1 "" ""))]
10523                 UNSPEC_TOCPTR))
10524    (match_dup 1)]
10525   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10526   "*
10528   char name[32];
10529   static char templ[32];
10531   get_ppc476_thunk_name (name);
10532   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10533   return templ;
10535   [(set_attr "type" "branch")
10536    (set_attr "length" "16")])
10538 (define_insn "load_toc_v4_PIC_2"
10539   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10540         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10541                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10542                              (match_operand:SI 3 "immediate_operand" "s")))))]
10543   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10544   "lwz %0,%2-%3(%1)"
10545   [(set_attr "type" "load")])
10547 (define_insn "load_toc_v4_PIC_3b"
10548   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10549         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10550                  (high:SI
10551                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10552                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10553   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10554   "addis %0,%1,%2-%3@ha")
10556 (define_insn "load_toc_v4_PIC_3c"
10557   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10558         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10559                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10560                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10561   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10562   "addi %0,%1,%2-%3@l")
10564 ;; If the TOC is shared over a translation unit, as happens with all
10565 ;; the kinds of PIC that we support, we need to restore the TOC
10566 ;; pointer only when jumping over units of translation.
10567 ;; On Darwin, we need to reload the picbase.
10569 (define_expand "builtin_setjmp_receiver"
10570   [(use (label_ref (match_operand 0 "" "")))]
10571   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10572    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10573    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10574   "
10576 #if TARGET_MACHO
10577   if (DEFAULT_ABI == ABI_DARWIN)
10578     {
10579       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10580       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10581       rtx tmplabrtx;
10582       char tmplab[20];
10584       crtl->uses_pic_offset_table = 1;
10585       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10586                                   CODE_LABEL_NUMBER (operands[0]));
10587       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10589       emit_insn (gen_load_macho_picbase (tmplabrtx));
10590       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10591       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10592     }
10593   else
10594 #endif
10595     rs6000_emit_load_toc_table (FALSE);
10596   DONE;
10599 ;; Largetoc support
10600 (define_insn "*largetoc_high"
10601   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10602         (high:DI
10603           (unspec [(match_operand:DI 1 "" "")
10604                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10605                   UNSPEC_TOCREL)))]
10606    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10607    "addis %0,%2,%1@toc@ha")
10609 (define_insn "*largetoc_high_aix<mode>"
10610   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10611         (high:P
10612           (unspec [(match_operand:P 1 "" "")
10613                    (match_operand:P 2 "gpc_reg_operand" "b")]
10614                   UNSPEC_TOCREL)))]
10615    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10616    "addis %0,%1@u(%2)")
10618 (define_insn "*largetoc_high_plus"
10619   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10620         (high:DI
10621           (plus:DI
10622             (unspec [(match_operand:DI 1 "" "")
10623                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10624                     UNSPEC_TOCREL)
10625             (match_operand:DI 3 "add_cint_operand" "n"))))]
10626    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10627    "addis %0,%2,%1+%3@toc@ha")
10629 (define_insn "*largetoc_high_plus_aix<mode>"
10630   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10631         (high:P
10632           (plus:P
10633             (unspec [(match_operand:P 1 "" "")
10634                      (match_operand:P 2 "gpc_reg_operand" "b")]
10635                     UNSPEC_TOCREL)
10636             (match_operand:P 3 "add_cint_operand" "n"))))]
10637    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10638    "addis %0,%1+%3@u(%2)")
10640 (define_insn "*largetoc_low"
10641   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10642         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10643                    (match_operand:DI 2 "" "")))]
10644    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10645    "addi %0,%1,%2@l")
10647 (define_insn "*largetoc_low_aix<mode>"
10648   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10649         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10650                    (match_operand:P 2 "" "")))]
10651    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10652    "la %0,%2@l(%1)")
10654 (define_insn_and_split "*tocref<mode>"
10655   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10656         (match_operand:P 1 "small_toc_ref" "R"))]
10657    "TARGET_TOC"
10658    "la %0,%a1"
10659    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10660   [(set (match_dup 0) (high:P (match_dup 1)))
10661    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10663 ;; Elf specific ways of loading addresses for non-PIC code.
10664 ;; The output of this could be r0, but we make a very strong
10665 ;; preference for a base register because it will usually
10666 ;; be needed there.
10667 (define_insn "elf_high"
10668   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10669         (high:SI (match_operand 1 "" "")))]
10670   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10671   "lis %0,%1@ha")
10673 (define_insn "elf_low"
10674   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10675         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10676                    (match_operand 2 "" "")))]
10677    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10678    "la %0,%2@l(%1)")
10680 ;; Call and call_value insns
10681 (define_expand "call"
10682   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10683                     (match_operand 1 "" ""))
10684               (use (match_operand 2 "" ""))
10685               (clobber (reg:SI LR_REGNO))])]
10686   ""
10687   "
10689 #if TARGET_MACHO
10690   if (MACHOPIC_INDIRECT)
10691     operands[0] = machopic_indirect_call_target (operands[0]);
10692 #endif
10694   gcc_assert (GET_CODE (operands[0]) == MEM);
10695   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10697   operands[0] = XEXP (operands[0], 0);
10699   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10700     {
10701       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10702       DONE;
10703     }
10705   if (GET_CODE (operands[0]) != SYMBOL_REF
10706       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10707     {
10708       if (INTVAL (operands[2]) & CALL_LONG)
10709         operands[0] = rs6000_longcall_ref (operands[0]);
10711       switch (DEFAULT_ABI)
10712         {
10713         case ABI_V4:
10714         case ABI_DARWIN:
10715           operands[0] = force_reg (Pmode, operands[0]);
10716           break;
10718         default:
10719           gcc_unreachable ();
10720         }
10721     }
10724 (define_expand "call_value"
10725   [(parallel [(set (match_operand 0 "" "")
10726                    (call (mem:SI (match_operand 1 "address_operand" ""))
10727                          (match_operand 2 "" "")))
10728               (use (match_operand 3 "" ""))
10729               (clobber (reg:SI LR_REGNO))])]
10730   ""
10731   "
10733 #if TARGET_MACHO
10734   if (MACHOPIC_INDIRECT)
10735     operands[1] = machopic_indirect_call_target (operands[1]);
10736 #endif
10738   gcc_assert (GET_CODE (operands[1]) == MEM);
10739   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10741   operands[1] = XEXP (operands[1], 0);
10743   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10744     {
10745       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10746       DONE;
10747     }
10749   if (GET_CODE (operands[1]) != SYMBOL_REF
10750       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10751     {
10752       if (INTVAL (operands[3]) & CALL_LONG)
10753         operands[1] = rs6000_longcall_ref (operands[1]);
10755       switch (DEFAULT_ABI)
10756         {
10757         case ABI_V4:
10758         case ABI_DARWIN:
10759           operands[1] = force_reg (Pmode, operands[1]);
10760           break;
10762         default:
10763           gcc_unreachable ();
10764         }
10765     }
10768 ;; Call to function in current module.  No TOC pointer reload needed.
10769 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10770 ;; either the function was not prototyped, or it was prototyped as a
10771 ;; variable argument function.  It is > 0 if FP registers were passed
10772 ;; and < 0 if they were not.
10774 (define_insn "*call_local32"
10775   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10776          (match_operand 1 "" "g,g"))
10777    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10778    (clobber (reg:SI LR_REGNO))]
10779   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10780   "*
10782   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10783     output_asm_insn (\"crxor 6,6,6\", operands);
10785   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10786     output_asm_insn (\"creqv 6,6,6\", operands);
10788   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10790   [(set_attr "type" "branch")
10791    (set_attr "length" "4,8")])
10793 (define_insn "*call_local64"
10794   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10795          (match_operand 1 "" "g,g"))
10796    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10797    (clobber (reg:SI LR_REGNO))]
10798   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10799   "*
10801   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10802     output_asm_insn (\"crxor 6,6,6\", operands);
10804   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10805     output_asm_insn (\"creqv 6,6,6\", operands);
10807   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10809   [(set_attr "type" "branch")
10810    (set_attr "length" "4,8")])
10812 (define_insn "*call_value_local32"
10813   [(set (match_operand 0 "" "")
10814         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10815               (match_operand 2 "" "g,g")))
10816    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10817    (clobber (reg:SI LR_REGNO))]
10818   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10819   "*
10821   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10822     output_asm_insn (\"crxor 6,6,6\", operands);
10824   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10825     output_asm_insn (\"creqv 6,6,6\", operands);
10827   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10829   [(set_attr "type" "branch")
10830    (set_attr "length" "4,8")])
10833 (define_insn "*call_value_local64"
10834   [(set (match_operand 0 "" "")
10835         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10836               (match_operand 2 "" "g,g")))
10837    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10838    (clobber (reg:SI LR_REGNO))]
10839   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10840   "*
10842   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10843     output_asm_insn (\"crxor 6,6,6\", operands);
10845   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10846     output_asm_insn (\"creqv 6,6,6\", operands);
10848   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10850   [(set_attr "type" "branch")
10851    (set_attr "length" "4,8")])
10854 ;; A function pointer under System V is just a normal pointer
10855 ;; operands[0] is the function pointer
10856 ;; operands[1] is the stack size to clean up
10857 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10858 ;; which indicates how to set cr1
10860 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10861   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10862          (match_operand 1 "" "g,g,g,g"))
10863    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10864    (clobber (reg:SI LR_REGNO))]
10865   "DEFAULT_ABI == ABI_V4
10866    || DEFAULT_ABI == ABI_DARWIN"
10868   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10869     output_asm_insn ("crxor 6,6,6", operands);
10871   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10872     output_asm_insn ("creqv 6,6,6", operands);
10874   return "b%T0l";
10876   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10877    (set_attr "length" "4,4,8,8")])
10879 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10880   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10881          (match_operand 1 "" "g,g"))
10882    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10883    (clobber (reg:SI LR_REGNO))]
10884   "(DEFAULT_ABI == ABI_DARWIN
10885    || (DEFAULT_ABI == ABI_V4
10886        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10888   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10889     output_asm_insn ("crxor 6,6,6", operands);
10891   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10892     output_asm_insn ("creqv 6,6,6", operands);
10894 #if TARGET_MACHO
10895   return output_call(insn, operands, 0, 2);
10896 #else
10897   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10898     {
10899       gcc_assert (!TARGET_SECURE_PLT);
10900       return "bl %z0@plt";
10901     }
10902   else
10903     return "bl %z0";
10904 #endif
10906   "DEFAULT_ABI == ABI_V4
10907    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10908    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10909   [(parallel [(call (mem:SI (match_dup 0))
10910                     (match_dup 1))
10911               (use (match_dup 2))
10912               (use (match_dup 3))
10913               (clobber (reg:SI LR_REGNO))])]
10915   operands[3] = pic_offset_table_rtx;
10917   [(set_attr "type" "branch,branch")
10918    (set_attr "length" "4,8")])
10920 (define_insn "*call_nonlocal_sysv_secure<mode>"
10921   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10922          (match_operand 1 "" "g,g"))
10923    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10924    (use (match_operand:SI 3 "register_operand" "r,r"))
10925    (clobber (reg:SI LR_REGNO))]
10926   "(DEFAULT_ABI == ABI_V4
10927     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10928     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10930   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10931     output_asm_insn ("crxor 6,6,6", operands);
10933   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10934     output_asm_insn ("creqv 6,6,6", operands);
10936   if (flag_pic == 2)
10937     /* The magic 32768 offset here and in the other sysv call insns
10938        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10939        See sysv4.h:toc_section.  */
10940     return "bl %z0+32768@plt";
10941   else
10942     return "bl %z0@plt";
10944   [(set_attr "type" "branch,branch")
10945    (set_attr "length" "4,8")])
10947 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10948   [(set (match_operand 0 "" "")
10949         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10950               (match_operand 2 "" "g,g,g,g")))
10951    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10952    (clobber (reg:SI LR_REGNO))]
10953   "DEFAULT_ABI == ABI_V4
10954    || DEFAULT_ABI == ABI_DARWIN"
10956   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10957     output_asm_insn ("crxor 6,6,6", operands);
10959   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10960     output_asm_insn ("creqv 6,6,6", operands);
10962   return "b%T1l";
10964   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10965    (set_attr "length" "4,4,8,8")])
10967 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10968   [(set (match_operand 0 "" "")
10969         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10970               (match_operand 2 "" "g,g")))
10971    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10972    (clobber (reg:SI LR_REGNO))]
10973   "(DEFAULT_ABI == ABI_DARWIN
10974    || (DEFAULT_ABI == ABI_V4
10975        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10977   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10978     output_asm_insn ("crxor 6,6,6", operands);
10980   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10981     output_asm_insn ("creqv 6,6,6", operands);
10983 #if TARGET_MACHO
10984   return output_call(insn, operands, 1, 3);
10985 #else
10986   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10987     {
10988       gcc_assert (!TARGET_SECURE_PLT);
10989       return "bl %z1@plt";
10990     }
10991   else
10992     return "bl %z1";
10993 #endif
10995   "DEFAULT_ABI == ABI_V4
10996    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10997    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10998   [(parallel [(set (match_dup 0)
10999                    (call (mem:SI (match_dup 1))
11000                          (match_dup 2)))
11001               (use (match_dup 3))
11002               (use (match_dup 4))
11003               (clobber (reg:SI LR_REGNO))])]
11005   operands[4] = pic_offset_table_rtx;
11007   [(set_attr "type" "branch,branch")
11008    (set_attr "length" "4,8")])
11010 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11011   [(set (match_operand 0 "" "")
11012         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11013               (match_operand 2 "" "g,g")))
11014    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11015    (use (match_operand:SI 4 "register_operand" "r,r"))
11016    (clobber (reg:SI LR_REGNO))]
11017   "(DEFAULT_ABI == ABI_V4
11018     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11019     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11021   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11022     output_asm_insn ("crxor 6,6,6", operands);
11024   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11025     output_asm_insn ("creqv 6,6,6", operands);
11027   if (flag_pic == 2)
11028     return "bl %z1+32768@plt";
11029   else
11030     return "bl %z1@plt";
11032   [(set_attr "type" "branch,branch")
11033    (set_attr "length" "4,8")])
11036 ;; Call to AIX abi function in the same module.
11038 (define_insn "*call_local_aix<mode>"
11039   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11040          (match_operand 1 "" "g"))
11041    (clobber (reg:P LR_REGNO))]
11042   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11043   "bl %z0"
11044   [(set_attr "type" "branch")
11045    (set_attr "length" "4")])
11047 (define_insn "*call_value_local_aix<mode>"
11048   [(set (match_operand 0 "" "")
11049         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11050               (match_operand 2 "" "g")))
11051    (clobber (reg:P LR_REGNO))]
11052   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11053   "bl %z1"
11054   [(set_attr "type" "branch")
11055    (set_attr "length" "4")])
11057 ;; Call to AIX abi function which may be in another module.
11058 ;; Restore the TOC pointer (r2) after the call.
11060 (define_insn "*call_nonlocal_aix<mode>"
11061   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11062          (match_operand 1 "" "g"))
11063    (clobber (reg:P LR_REGNO))]
11064   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11065   "bl %z0\;nop"
11066   [(set_attr "type" "branch")
11067    (set_attr "length" "8")])
11069 (define_insn "*call_value_nonlocal_aix<mode>"
11070   [(set (match_operand 0 "" "")
11071         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11072               (match_operand 2 "" "g")))
11073    (clobber (reg:P LR_REGNO))]
11074   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11075   "bl %z1\;nop"
11076   [(set_attr "type" "branch")
11077    (set_attr "length" "8")])
11079 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11080 ;; Operand0 is the addresss of the function to call
11081 ;; Operand2 is the location in the function descriptor to load r2 from
11082 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11084 (define_insn "*call_indirect_aix<mode>"
11085   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11086          (match_operand 1 "" "g,g"))
11087    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11088    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11089    (clobber (reg:P LR_REGNO))]
11090   "DEFAULT_ABI == ABI_AIX"
11091   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11092   [(set_attr "type" "jmpreg")
11093    (set_attr "length" "12")])
11095 (define_insn "*call_value_indirect_aix<mode>"
11096   [(set (match_operand 0 "" "")
11097         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11098               (match_operand 2 "" "g,g")))
11099    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11100    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11101    (clobber (reg:P LR_REGNO))]
11102   "DEFAULT_ABI == ABI_AIX"
11103   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11104   [(set_attr "type" "jmpreg")
11105    (set_attr "length" "12")])
11107 ;; Call to indirect functions with the ELFv2 ABI.
11108 ;; Operand0 is the addresss of the function to call
11109 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11111 (define_insn "*call_indirect_elfv2<mode>"
11112   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11113          (match_operand 1 "" "g,g"))
11114    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11115    (clobber (reg:P LR_REGNO))]
11116   "DEFAULT_ABI == ABI_ELFv2"
11117   "b%T0l\;<ptrload> 2,%2(1)"
11118   [(set_attr "type" "jmpreg")
11119    (set_attr "length" "8")])
11121 (define_insn "*call_value_indirect_elfv2<mode>"
11122   [(set (match_operand 0 "" "")
11123         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11124               (match_operand 2 "" "g,g")))
11125    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11126    (clobber (reg:P LR_REGNO))]
11127   "DEFAULT_ABI == ABI_ELFv2"
11128   "b%T1l\;<ptrload> 2,%3(1)"
11129   [(set_attr "type" "jmpreg")
11130    (set_attr "length" "8")])
11133 ;; Call subroutine returning any type.
11134 (define_expand "untyped_call"
11135   [(parallel [(call (match_operand 0 "" "")
11136                     (const_int 0))
11137               (match_operand 1 "" "")
11138               (match_operand 2 "" "")])]
11139   ""
11140   "
11142   int i;
11144   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11146   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11147     {
11148       rtx set = XVECEXP (operands[2], 0, i);
11149       emit_move_insn (SET_DEST (set), SET_SRC (set));
11150     }
11152   /* The optimizer does not know that the call sets the function value
11153      registers we stored in the result block.  We avoid problems by
11154      claiming that all hard registers are used and clobbered at this
11155      point.  */
11156   emit_insn (gen_blockage ());
11158   DONE;
11161 ;; sibling call patterns
11162 (define_expand "sibcall"
11163   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11164                     (match_operand 1 "" ""))
11165               (use (match_operand 2 "" ""))
11166               (simple_return)])]
11167   ""
11168   "
11170 #if TARGET_MACHO
11171   if (MACHOPIC_INDIRECT)
11172     operands[0] = machopic_indirect_call_target (operands[0]);
11173 #endif
11175   gcc_assert (GET_CODE (operands[0]) == MEM);
11176   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11178   operands[0] = XEXP (operands[0], 0);
11180   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11181     {
11182       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11183       DONE;
11184     }
11187 (define_expand "sibcall_value"
11188   [(parallel [(set (match_operand 0 "register_operand" "")
11189                 (call (mem:SI (match_operand 1 "address_operand" ""))
11190                       (match_operand 2 "" "")))
11191               (use (match_operand 3 "" ""))
11192               (simple_return)])]
11193   ""
11194   "
11196 #if TARGET_MACHO
11197   if (MACHOPIC_INDIRECT)
11198     operands[1] = machopic_indirect_call_target (operands[1]);
11199 #endif
11201   gcc_assert (GET_CODE (operands[1]) == MEM);
11202   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11204   operands[1] = XEXP (operands[1], 0);
11206   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11207     {
11208       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11209       DONE;
11210     }
11213 (define_insn "*sibcall_local32"
11214   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11215          (match_operand 1 "" "g,g"))
11216    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11217    (simple_return)]
11218   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11219   "*
11221   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11222     output_asm_insn (\"crxor 6,6,6\", operands);
11224   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11225     output_asm_insn (\"creqv 6,6,6\", operands);
11227   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11229   [(set_attr "type" "branch")
11230    (set_attr "length" "4,8")])
11232 (define_insn "*sibcall_local64"
11233   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11234          (match_operand 1 "" "g,g"))
11235    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11236    (simple_return)]
11237   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11238   "*
11240   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11241     output_asm_insn (\"crxor 6,6,6\", operands);
11243   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11244     output_asm_insn (\"creqv 6,6,6\", operands);
11246   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11248   [(set_attr "type" "branch")
11249    (set_attr "length" "4,8")])
11251 (define_insn "*sibcall_value_local32"
11252   [(set (match_operand 0 "" "")
11253         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11254               (match_operand 2 "" "g,g")))
11255    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11256    (simple_return)]
11257   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11258   "*
11260   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11261     output_asm_insn (\"crxor 6,6,6\", operands);
11263   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11264     output_asm_insn (\"creqv 6,6,6\", operands);
11266   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11268   [(set_attr "type" "branch")
11269    (set_attr "length" "4,8")])
11271 (define_insn "*sibcall_value_local64"
11272   [(set (match_operand 0 "" "")
11273         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11274               (match_operand 2 "" "g,g")))
11275    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11276    (simple_return)]
11277   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11278   "*
11280   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11281     output_asm_insn (\"crxor 6,6,6\", operands);
11283   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11284     output_asm_insn (\"creqv 6,6,6\", operands);
11286   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11288   [(set_attr "type" "branch")
11289    (set_attr "length" "4,8")])
11291 (define_insn "*sibcall_nonlocal_sysv<mode>"
11292   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11293          (match_operand 1 "" ""))
11294    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11295    (simple_return)]
11296   "(DEFAULT_ABI == ABI_DARWIN
11297     || DEFAULT_ABI == ABI_V4)
11298    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11299   "*
11301   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11302     output_asm_insn (\"crxor 6,6,6\", operands);
11304   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11305     output_asm_insn (\"creqv 6,6,6\", operands);
11307   if (which_alternative >= 2)
11308     return \"b%T0\";
11309   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11310     {
11311       gcc_assert (!TARGET_SECURE_PLT);
11312       return \"b %z0@plt\";
11313     }
11314   else
11315     return \"b %z0\";
11317   [(set_attr "type" "branch")
11318    (set_attr "length" "4,8,4,8")])
11320 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11321   [(set (match_operand 0 "" "")
11322         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11323               (match_operand 2 "" "")))
11324    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11325    (simple_return)]
11326   "(DEFAULT_ABI == ABI_DARWIN
11327     || DEFAULT_ABI == ABI_V4)
11328    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11329   "*
11331   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11332     output_asm_insn (\"crxor 6,6,6\", operands);
11334   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11335     output_asm_insn (\"creqv 6,6,6\", operands);
11337   if (which_alternative >= 2)
11338     return \"b%T1\";
11339   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11340     {
11341       gcc_assert (!TARGET_SECURE_PLT);
11342       return \"b %z1@plt\";
11343     }
11344   else
11345     return \"b %z1\";
11347   [(set_attr "type" "branch")
11348    (set_attr "length" "4,8,4,8")])
11350 ;; AIX ABI sibling call patterns.
11352 (define_insn "*sibcall_aix<mode>"
11353   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11354          (match_operand 1 "" "g,g"))
11355    (simple_return)]
11356   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11357   "@
11358    b %z0
11359    b%T0"
11360   [(set_attr "type" "branch")
11361    (set_attr "length" "4")])
11363 (define_insn "*sibcall_value_aix<mode>"
11364   [(set (match_operand 0 "" "")
11365         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11366               (match_operand 2 "" "g,g")))
11367    (simple_return)]
11368   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11369   "@
11370    b %z1
11371    b%T1"
11372   [(set_attr "type" "branch")
11373    (set_attr "length" "4")])
11375 (define_expand "sibcall_epilogue"
11376   [(use (const_int 0))]
11377   ""
11379   if (!TARGET_SCHED_PROLOG)
11380     emit_insn (gen_blockage ());
11381   rs6000_emit_epilogue (TRUE);
11382   DONE;
11385 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11386 ;; all of memory.  This blocks insns from being moved across this point.
11388 (define_insn "blockage"
11389   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11390   ""
11391   "")
11393 (define_expand "probe_stack_address"
11394   [(use (match_operand 0 "address_operand"))]
11395   ""
11397   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11398   MEM_VOLATILE_P (operands[0]) = 1;
11400   if (TARGET_64BIT)
11401     emit_insn (gen_probe_stack_di (operands[0]));
11402   else
11403     emit_insn (gen_probe_stack_si (operands[0]));
11404   DONE;
11407 (define_insn "probe_stack_<mode>"
11408   [(set (match_operand:P 0 "memory_operand" "=m")
11409         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11410   ""
11412   operands[1] = gen_rtx_REG (Pmode, 0);
11413   return "st<wd>%U0%X0 %1,%0";
11415   [(set_attr "type" "store")
11416    (set (attr "update")
11417         (if_then_else (match_operand 0 "update_address_mem")
11418                       (const_string "yes")
11419                       (const_string "no")))
11420    (set (attr "indexed")
11421         (if_then_else (match_operand 0 "indexed_address_mem")
11422                       (const_string "yes")
11423                       (const_string "no")))
11424    (set_attr "length" "4")])
11426 (define_insn "probe_stack_range<P:mode>"
11427   [(set (match_operand:P 0 "register_operand" "=r")
11428         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11429                             (match_operand:P 2 "register_operand" "r")]
11430                            UNSPECV_PROBE_STACK_RANGE))]
11431   ""
11432   "* return output_probe_stack_range (operands[0], operands[2]);"
11433   [(set_attr "type" "three")])
11435 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11436 ;; signed & unsigned, and one type of branch.
11438 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11439 ;; insns, and branches.
11441 (define_expand "cbranch<mode>4"
11442   [(use (match_operator 0 "rs6000_cbranch_operator"
11443          [(match_operand:GPR 1 "gpc_reg_operand" "")
11444           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11445    (use (match_operand 3 ""))]
11446   ""
11447   "
11449   /* Take care of the possibility that operands[2] might be negative but
11450      this might be a logical operation.  That insn doesn't exist.  */
11451   if (GET_CODE (operands[2]) == CONST_INT
11452       && INTVAL (operands[2]) < 0)
11453     {
11454       operands[2] = force_reg (<MODE>mode, operands[2]);
11455       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11456                                     GET_MODE (operands[0]),
11457                                     operands[1], operands[2]);
11458    }
11460   rs6000_emit_cbranch (<MODE>mode, operands);
11461   DONE;
11464 (define_expand "cbranch<mode>4"
11465   [(use (match_operator 0 "rs6000_cbranch_operator"
11466          [(match_operand:FP 1 "gpc_reg_operand" "")
11467           (match_operand:FP 2 "gpc_reg_operand" "")]))
11468    (use (match_operand 3 ""))]
11469   ""
11470   "
11472   rs6000_emit_cbranch (<MODE>mode, operands);
11473   DONE;
11476 (define_expand "cstore<mode>4_signed"
11477   [(use (match_operator 1 "signed_comparison_operator"
11478          [(match_operand:P 2 "gpc_reg_operand")
11479           (match_operand:P 3 "gpc_reg_operand")]))
11480    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11481   ""
11483   enum rtx_code cond_code = GET_CODE (operands[1]);
11485   rtx op0 = operands[0];
11486   rtx op1 = operands[2];
11487   rtx op2 = operands[3];
11489   if (cond_code == GE || cond_code == LT)
11490     {
11491       cond_code = swap_condition (cond_code);
11492       std::swap (op1, op2);
11493     }
11495   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11496   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11497   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11499   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11500   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11501   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11503   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11505   if (cond_code == LE)
11506     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11507   else
11508     {
11509       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11510       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11511       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11512     }
11514   DONE;
11517 (define_expand "cstore<mode>4_unsigned"
11518   [(use (match_operator 1 "unsigned_comparison_operator"
11519          [(match_operand:P 2 "gpc_reg_operand")
11520           (match_operand:P 3 "reg_or_short_operand")]))
11521    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11522   ""
11524   enum rtx_code cond_code = GET_CODE (operands[1]);
11526   rtx op0 = operands[0];
11527   rtx op1 = operands[2];
11528   rtx op2 = operands[3];
11530   if (cond_code == GEU || cond_code == LTU)
11531     {
11532       cond_code = swap_condition (cond_code);
11533       std::swap (op1, op2);
11534     }
11536   if (!gpc_reg_operand (op1, <MODE>mode))
11537     op1 = force_reg (<MODE>mode, op1);
11538   if (!reg_or_short_operand (op2, <MODE>mode))
11539     op2 = force_reg (<MODE>mode, op2);
11541   rtx tmp = gen_reg_rtx (<MODE>mode);
11542   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11544   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11545   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11547   if (cond_code == LEU)
11548     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11549   else
11550     emit_insn (gen_neg<mode>2 (op0, tmp2));
11552   DONE;
11555 (define_expand "cstore_si_as_di"
11556   [(use (match_operator 1 "unsigned_comparison_operator"
11557          [(match_operand:SI 2 "gpc_reg_operand")
11558           (match_operand:SI 3 "reg_or_short_operand")]))
11559    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11560   ""
11562   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11563   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11565   operands[2] = force_reg (SImode, operands[2]);
11566   operands[3] = force_reg (SImode, operands[3]);
11567   rtx op1 = gen_reg_rtx (DImode);
11568   rtx op2 = gen_reg_rtx (DImode);
11569   convert_move (op1, operands[2], uns_flag);
11570   convert_move (op2, operands[3], uns_flag);
11572   if (cond_code == GT || cond_code == LE)
11573     {
11574       cond_code = swap_condition (cond_code);
11575       std::swap (op1, op2);
11576     }
11578   rtx tmp = gen_reg_rtx (DImode);
11579   rtx tmp2 = gen_reg_rtx (DImode);
11580   emit_insn (gen_subdi3 (tmp, op1, op2));
11581   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11583   rtx tmp3;
11584   switch (cond_code)
11585     {
11586     default:
11587       gcc_unreachable ();
11588     case LT:
11589       tmp3 = tmp2;
11590       break;
11591     case GE:
11592       tmp3 = gen_reg_rtx (DImode);
11593       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11594       break;
11595     }
11597   convert_move (operands[0], tmp3, 1);
11599   DONE;
11602 (define_expand "cstore<mode>4_signed_imm"
11603   [(use (match_operator 1 "signed_comparison_operator"
11604          [(match_operand:GPR 2 "gpc_reg_operand")
11605           (match_operand:GPR 3 "immediate_operand")]))
11606    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11607   ""
11609   bool invert = false;
11611   enum rtx_code cond_code = GET_CODE (operands[1]);
11613   rtx op0 = operands[0];
11614   rtx op1 = operands[2];
11615   HOST_WIDE_INT val = INTVAL (operands[3]);
11617   if (cond_code == GE || cond_code == GT)
11618     {
11619       cond_code = reverse_condition (cond_code);
11620       invert = true;
11621     }
11623   if (cond_code == LE)
11624     val++;
11626   rtx tmp = gen_reg_rtx (<MODE>mode);
11627   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11628   rtx x = gen_reg_rtx (<MODE>mode);
11629   if (val < 0)
11630     emit_insn (gen_and<mode>3 (x, op1, tmp));
11631   else
11632     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11634   if (invert)
11635     {
11636       rtx tmp = gen_reg_rtx (<MODE>mode);
11637       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11638       x = tmp;
11639     }
11641   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11642   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11644   DONE;
11647 (define_expand "cstore<mode>4_unsigned_imm"
11648   [(use (match_operator 1 "unsigned_comparison_operator"
11649          [(match_operand:GPR 2 "gpc_reg_operand")
11650           (match_operand:GPR 3 "immediate_operand")]))
11651    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11652   ""
11654   bool invert = false;
11656   enum rtx_code cond_code = GET_CODE (operands[1]);
11658   rtx op0 = operands[0];
11659   rtx op1 = operands[2];
11660   HOST_WIDE_INT val = INTVAL (operands[3]);
11662   if (cond_code == GEU || cond_code == GTU)
11663     {
11664       cond_code = reverse_condition (cond_code);
11665       invert = true;
11666     }
11668   if (cond_code == LEU)
11669     val++;
11671   rtx tmp = gen_reg_rtx (<MODE>mode);
11672   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11673   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11674   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11675   rtx x = gen_reg_rtx (<MODE>mode);
11676   if (val < 0)
11677     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11678   else
11679     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11681   if (invert)
11682     {
11683       rtx tmp = gen_reg_rtx (<MODE>mode);
11684       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11685       x = tmp;
11686     }
11688   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11689   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11691   DONE;
11694 (define_expand "cstore<mode>4"
11695   [(use (match_operator 1 "rs6000_cbranch_operator"
11696          [(match_operand:GPR 2 "gpc_reg_operand")
11697           (match_operand:GPR 3 "reg_or_short_operand")]))
11698    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11699   ""
11701   /* Use ISEL if the user asked for it.  */
11702   if (TARGET_ISEL)
11703     rs6000_emit_sISEL (<MODE>mode, operands);
11705   /* Expanding EQ and NE directly to some machine instructions does not help
11706      but does hurt combine.  So don't.  */
11707   else if (GET_CODE (operands[1]) == EQ)
11708     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11709   else if (<MODE>mode == Pmode
11710            && GET_CODE (operands[1]) == NE)
11711     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11712   else if (GET_CODE (operands[1]) == NE)
11713     {
11714       rtx tmp = gen_reg_rtx (<MODE>mode);
11715       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11716       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11717     }
11719   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11720      etc. combinations magically work out just right.  */
11721   else if (<MODE>mode == Pmode
11722            && unsigned_comparison_operator (operands[1], VOIDmode))
11723     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11724                                            operands[2], operands[3]));
11726   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11727   else if (<MODE>mode == SImode && Pmode == DImode)
11728     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11729                                     operands[2], operands[3]));
11731   /* For signed comparisons against a constant, we can do some simple
11732      bit-twiddling.  */
11733   else if (signed_comparison_operator (operands[1], VOIDmode)
11734            && CONST_INT_P (operands[3]))
11735     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11736                                              operands[2], operands[3]));
11738   /* And similarly for unsigned comparisons.  */
11739   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11740            && CONST_INT_P (operands[3]))
11741     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11742                                                operands[2], operands[3]));
11744   /* We also do not want to use mfcr for signed comparisons.  */
11745   else if (<MODE>mode == Pmode
11746            && signed_comparison_operator (operands[1], VOIDmode))
11747     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11748                                          operands[2], operands[3]));
11750   /* Everything else, use the mfcr brute force.  */
11751   else
11752     rs6000_emit_sCOND (<MODE>mode, operands);
11754   DONE;
11757 (define_expand "cstore<mode>4"
11758   [(use (match_operator 1 "rs6000_cbranch_operator"
11759          [(match_operand:FP 2 "gpc_reg_operand")
11760           (match_operand:FP 3 "gpc_reg_operand")]))
11761    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11762   ""
11764   rs6000_emit_sCOND (<MODE>mode, operands);
11765   DONE;
11769 (define_expand "stack_protect_set"
11770   [(match_operand 0 "memory_operand")
11771    (match_operand 1 "memory_operand")]
11772   ""
11774   if (rs6000_stack_protector_guard == SSP_TLS)
11775     {
11776       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11777       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11778       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11779       operands[1] = gen_rtx_MEM (Pmode, addr);
11780     }
11782   if (TARGET_64BIT)
11783     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11784   else
11785     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11787   DONE;
11790 (define_insn "stack_protect_setsi"
11791   [(set (match_operand:SI 0 "memory_operand" "=m")
11792         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11793    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11794   "TARGET_32BIT"
11795   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11796   [(set_attr "type" "three")
11797    (set_attr "length" "12")])
11799 (define_insn "stack_protect_setdi"
11800   [(set (match_operand:DI 0 "memory_operand" "=Y")
11801         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11802    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11803   "TARGET_64BIT"
11804   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11805   [(set_attr "type" "three")
11806    (set_attr "length" "12")])
11808 (define_expand "stack_protect_test"
11809   [(match_operand 0 "memory_operand")
11810    (match_operand 1 "memory_operand")
11811    (match_operand 2 "")]
11812   ""
11814   rtx guard = operands[1];
11816   if (rs6000_stack_protector_guard == SSP_TLS)
11817     {
11818       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11819       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11820       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11821       guard = gen_rtx_MEM (Pmode, addr);
11822     }
11824   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11825   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11826   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11827   emit_jump_insn (jump);
11829   DONE;
11832 (define_insn "stack_protect_testsi"
11833   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11834         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11835                       (match_operand:SI 2 "memory_operand" "m,m")]
11836                      UNSPEC_SP_TEST))
11837    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11838    (clobber (match_scratch:SI 3 "=&r,&r"))]
11839   "TARGET_32BIT"
11840   "@
11841    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11842    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11843   [(set_attr "length" "16,20")])
11845 (define_insn "stack_protect_testdi"
11846   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11847         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11848                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11849                      UNSPEC_SP_TEST))
11850    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11851    (clobber (match_scratch:DI 3 "=&r,&r"))]
11852   "TARGET_64BIT"
11853   "@
11854    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11855    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11856   [(set_attr "length" "16,20")])
11859 ;; Here are the actual compare insns.
11860 (define_insn "*cmp<mode>_signed"
11861   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11862         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11863                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11864   ""
11865   "cmp<wd>%I2 %0,%1,%2"
11866   [(set_attr "type" "cmp")])
11868 (define_insn "*cmp<mode>_unsigned"
11869   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11870         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11871                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11872   ""
11873   "cmpl<wd>%I2 %0,%1,%2"
11874   [(set_attr "type" "cmp")])
11876 ;; If we are comparing a register for equality with a large constant,
11877 ;; we can do this with an XOR followed by a compare.  But this is profitable
11878 ;; only if the large constant is only used for the comparison (and in this
11879 ;; case we already have a register to reuse as scratch).
11881 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11882 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11884 (define_peephole2
11885   [(set (match_operand:SI 0 "register_operand")
11886         (match_operand:SI 1 "logical_const_operand" ""))
11887    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11888                        [(match_dup 0)
11889                         (match_operand:SI 2 "logical_const_operand" "")]))
11890    (set (match_operand:CC 4 "cc_reg_operand" "")
11891         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11892                     (match_dup 0)))
11893    (set (pc)
11894         (if_then_else (match_operator 6 "equality_operator"
11895                        [(match_dup 4) (const_int 0)])
11896                       (match_operand 7 "" "")
11897                       (match_operand 8 "" "")))]
11898   "peep2_reg_dead_p (3, operands[0])
11899    && peep2_reg_dead_p (4, operands[4])
11900    && REGNO (operands[0]) != REGNO (operands[5])"
11901  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11902   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11903   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11906   /* Get the constant we are comparing against, and see what it looks like
11907      when sign-extended from 16 to 32 bits.  Then see what constant we could
11908      XOR with SEXTC to get the sign-extended value.  */
11909   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11910                                               SImode,
11911                                               operands[1], operands[2]);
11912   HOST_WIDE_INT c = INTVAL (cnst);
11913   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11914   HOST_WIDE_INT xorv = c ^ sextc;
11916   operands[9] = GEN_INT (xorv);
11917   operands[10] = GEN_INT (sextc);
11920 ;; The following two insns don't exist as single insns, but if we provide
11921 ;; them, we can swap an add and compare, which will enable us to overlap more
11922 ;; of the required delay between a compare and branch.  We generate code for
11923 ;; them by splitting.
11925 (define_insn ""
11926   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11927         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11928                     (match_operand:SI 2 "short_cint_operand" "i")))
11929    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11930         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11931   ""
11932   "#"
11933   [(set_attr "length" "8")])
11935 (define_insn ""
11936   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11937         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11938                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11939    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11940         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11941   ""
11942   "#"
11943   [(set_attr "length" "8")])
11945 (define_split
11946   [(set (match_operand:CC 3 "cc_reg_operand" "")
11947         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11948                     (match_operand:SI 2 "short_cint_operand" "")))
11949    (set (match_operand:SI 0 "gpc_reg_operand" "")
11950         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11951   ""
11952   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11953    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11955 (define_split
11956   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11957         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11958                        (match_operand:SI 2 "u_short_cint_operand" "")))
11959    (set (match_operand:SI 0 "gpc_reg_operand" "")
11960         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11961   ""
11962   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11963    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11965 ;; Only need to compare second words if first words equal
11966 (define_insn "*cmp<mode>_internal1"
11967   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11968         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11969                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11970   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11971    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11972   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11973   [(set_attr "type" "fpcompare")
11974    (set_attr "length" "12")])
11976 (define_insn_and_split "*cmp<mode>_internal2"
11977   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11978         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11979                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11980     (clobber (match_scratch:DF 3 "=d"))
11981     (clobber (match_scratch:DF 4 "=d"))
11982     (clobber (match_scratch:DF 5 "=d"))
11983     (clobber (match_scratch:DF 6 "=d"))
11984     (clobber (match_scratch:DF 7 "=d"))
11985     (clobber (match_scratch:DF 8 "=d"))
11986     (clobber (match_scratch:DF 9 "=d"))
11987     (clobber (match_scratch:DF 10 "=d"))
11988     (clobber (match_scratch:GPR 11 "=b"))]
11989   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11990    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11991   "#"
11992   "&& reload_completed"
11993   [(set (match_dup 3) (match_dup 14))
11994    (set (match_dup 4) (match_dup 15))
11995    (set (match_dup 9) (abs:DF (match_dup 5)))
11996    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11997    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11998                            (label_ref (match_dup 12))
11999                            (pc)))
12000    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12001    (set (pc) (label_ref (match_dup 13)))
12002    (match_dup 12)
12003    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12004    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12005    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12006    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12007    (match_dup 13)]
12009   REAL_VALUE_TYPE rv;
12010   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12011   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12013   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12014   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12015   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12016   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12017   operands[12] = gen_label_rtx ();
12018   operands[13] = gen_label_rtx ();
12019   real_inf (&rv);
12020   operands[14] = force_const_mem (DFmode,
12021                                   const_double_from_real_value (rv, DFmode));
12022   operands[15] = force_const_mem (DFmode,
12023                                   const_double_from_real_value (dconst0,
12024                                                                 DFmode));
12025   if (TARGET_TOC)
12026     {
12027       rtx tocref;
12028       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12029       operands[14] = gen_const_mem (DFmode, tocref);
12030       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12031       operands[15] = gen_const_mem (DFmode, tocref);
12032       set_mem_alias_set (operands[14], get_TOC_alias_set ());
12033       set_mem_alias_set (operands[15], get_TOC_alias_set ());
12034     }
12037 ;; Now we have the scc insns.  We can do some combinations because of the
12038 ;; way the machine works.
12040 ;; Note that this is probably faster if we can put an insn between the
12041 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
12042 ;; cases the insns below which don't use an intermediate CR field will
12043 ;; be used instead.
12044 (define_insn ""
12045   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12046         (match_operator:SI 1 "scc_comparison_operator"
12047                            [(match_operand 2 "cc_reg_operand" "y")
12048                             (const_int 0)]))]
12049   ""
12050   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12051   [(set (attr "type")
12052      (cond [(match_test "TARGET_MFCRF")
12053                 (const_string "mfcrf")
12054            ]
12055         (const_string "mfcr")))
12056    (set_attr "length" "8")])
12058 ;; Same as above, but get the GT bit.
12059 (define_insn "move_from_CR_gt_bit"
12060   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12061         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12062   "TARGET_HARD_FLOAT && !TARGET_FPRS"
12063   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12064   [(set_attr "type" "mfcr")
12065    (set_attr "length" "8")])
12067 ;; Same as above, but get the OV/ORDERED bit.
12068 (define_insn "move_from_CR_ov_bit"
12069   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12070         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12071                    UNSPEC_MV_CR_OV))]
12072   "TARGET_ISEL"
12073   "mfcr %0\;rlwinm %0,%0,%t1,1"
12074   [(set_attr "type" "mfcr")
12075    (set_attr "length" "8")])
12077 (define_insn ""
12078   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12079         (match_operator:DI 1 "scc_comparison_operator"
12080                            [(match_operand 2 "cc_reg_operand" "y")
12081                             (const_int 0)]))]
12082   "TARGET_POWERPC64"
12083   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12084   [(set (attr "type")
12085      (cond [(match_test "TARGET_MFCRF")
12086                 (const_string "mfcrf")
12087            ]
12088         (const_string "mfcr")))
12089    (set_attr "length" "8")])
12091 (define_insn ""
12092   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12093         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12094                                        [(match_operand 2 "cc_reg_operand" "y,y")
12095                                         (const_int 0)])
12096                     (const_int 0)))
12097    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12098         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12099   "TARGET_32BIT"
12100   "@
12101    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12102    #"
12103   [(set_attr "type" "shift")
12104    (set_attr "dot" "yes")
12105    (set_attr "length" "8,16")])
12107 (define_split
12108   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12109         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12110                                        [(match_operand 2 "cc_reg_operand" "")
12111                                         (const_int 0)])
12112                     (const_int 0)))
12113    (set (match_operand:SI 3 "gpc_reg_operand" "")
12114         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12115   "TARGET_32BIT && reload_completed"
12116   [(set (match_dup 3)
12117         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12118    (set (match_dup 0)
12119         (compare:CC (match_dup 3)
12120                     (const_int 0)))]
12121   "")
12123 (define_insn ""
12124   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12125         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12126                                       [(match_operand 2 "cc_reg_operand" "y")
12127                                        (const_int 0)])
12128                    (match_operand:SI 3 "const_int_operand" "n")))]
12129   ""
12130   "*
12132   int is_bit = ccr_bit (operands[1], 1);
12133   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12134   int count;
12136   if (is_bit >= put_bit)
12137     count = is_bit - put_bit;
12138   else
12139     count = 32 - (put_bit - is_bit);
12141   operands[4] = GEN_INT (count);
12142   operands[5] = GEN_INT (put_bit);
12144   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12146   [(set (attr "type")
12147      (cond [(match_test "TARGET_MFCRF")
12148                 (const_string "mfcrf")
12149            ]
12150         (const_string "mfcr")))
12151    (set_attr "length" "8")])
12153 (define_insn ""
12154   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12155         (compare:CC
12156          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12157                                        [(match_operand 2 "cc_reg_operand" "y,y")
12158                                         (const_int 0)])
12159                     (match_operand:SI 3 "const_int_operand" "n,n"))
12160          (const_int 0)))
12161    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12162         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12163                    (match_dup 3)))]
12164   ""
12165   "*
12167   int is_bit = ccr_bit (operands[1], 1);
12168   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12169   int count;
12171   /* Force split for non-cc0 compare.  */
12172   if (which_alternative == 1)
12173      return \"#\";
12175   if (is_bit >= put_bit)
12176     count = is_bit - put_bit;
12177   else
12178     count = 32 - (put_bit - is_bit);
12180   operands[5] = GEN_INT (count);
12181   operands[6] = GEN_INT (put_bit);
12183   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12185   [(set_attr "type" "shift")
12186    (set_attr "dot" "yes")
12187    (set_attr "length" "8,16")])
12189 (define_split
12190   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12191         (compare:CC
12192          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12193                                        [(match_operand 2 "cc_reg_operand" "")
12194                                         (const_int 0)])
12195                     (match_operand:SI 3 "const_int_operand" ""))
12196          (const_int 0)))
12197    (set (match_operand:SI 4 "gpc_reg_operand" "")
12198         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12199                    (match_dup 3)))]
12200   "reload_completed"
12201   [(set (match_dup 4)
12202         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12203                    (match_dup 3)))
12204    (set (match_dup 0)
12205         (compare:CC (match_dup 4)
12206                     (const_int 0)))]
12207   "")
12210 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12211                               (DI "rKJI")])
12213 (define_insn_and_split "eq<mode>3"
12214   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12215         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12216                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12217    (clobber (match_scratch:GPR 3 "=r"))
12218    (clobber (match_scratch:GPR 4 "=r"))]
12219   ""
12220   "#"
12221   ""
12222   [(set (match_dup 4)
12223         (clz:GPR (match_dup 3)))
12224    (set (match_dup 0)
12225         (lshiftrt:GPR (match_dup 4)
12226                       (match_dup 5)))]
12228   operands[3] = rs6000_emit_eqne (<MODE>mode,
12229                                   operands[1], operands[2], operands[3]);
12231   if (GET_CODE (operands[4]) == SCRATCH)
12232     operands[4] = gen_reg_rtx (<MODE>mode);
12234   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12236   [(set (attr "length")
12237         (if_then_else (match_test "operands[2] == const0_rtx")
12238                       (const_string "8")
12239                       (const_string "12")))])
12241 (define_insn_and_split "ne<mode>3"
12242   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12243         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12244               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12245    (clobber (match_scratch:P 3 "=r"))
12246    (clobber (match_scratch:P 4 "=r"))
12247    (clobber (reg:P CA_REGNO))]
12248   "!TARGET_ISEL"
12249   "#"
12250   ""
12251   [(parallel [(set (match_dup 4)
12252                    (plus:P (match_dup 3)
12253                            (const_int -1)))
12254               (set (reg:P CA_REGNO)
12255                    (ne:P (match_dup 3)
12256                          (const_int 0)))])
12257    (parallel [(set (match_dup 0)
12258                    (plus:P (plus:P (not:P (match_dup 4))
12259                                    (reg:P CA_REGNO))
12260                            (match_dup 3)))
12261               (clobber (reg:P CA_REGNO))])]
12263   operands[3] = rs6000_emit_eqne (<MODE>mode,
12264                                   operands[1], operands[2], operands[3]);
12266   if (GET_CODE (operands[4]) == SCRATCH)
12267     operands[4] = gen_reg_rtx (<MODE>mode);
12269   [(set (attr "length")
12270         (if_then_else (match_test "operands[2] == const0_rtx")
12271                       (const_string "8")
12272                       (const_string "12")))])
12274 (define_insn_and_split "*neg_eq_<mode>"
12275   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12276         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12277                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12278    (clobber (match_scratch:P 3 "=r"))
12279    (clobber (match_scratch:P 4 "=r"))
12280    (clobber (reg:P CA_REGNO))]
12281   ""
12282   "#"
12283   ""
12284   [(parallel [(set (match_dup 4)
12285                    (plus:P (match_dup 3)
12286                            (const_int -1)))
12287               (set (reg:P CA_REGNO)
12288                    (ne:P (match_dup 3)
12289                          (const_int 0)))])
12290    (parallel [(set (match_dup 0)
12291                    (plus:P (reg:P CA_REGNO)
12292                            (const_int -1)))
12293               (clobber (reg:P CA_REGNO))])]
12295   operands[3] = rs6000_emit_eqne (<MODE>mode,
12296                                   operands[1], operands[2], operands[3]);
12298   if (GET_CODE (operands[4]) == SCRATCH)
12299     operands[4] = gen_reg_rtx (<MODE>mode);
12301   [(set (attr "length")
12302         (if_then_else (match_test "operands[2] == const0_rtx")
12303                       (const_string "8")
12304                       (const_string "12")))])
12306 (define_insn_and_split "*neg_ne_<mode>"
12307   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12308         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12309                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12310    (clobber (match_scratch:P 3 "=r"))
12311    (clobber (match_scratch:P 4 "=r"))
12312    (clobber (reg:P CA_REGNO))]
12313   ""
12314   "#"
12315   ""
12316   [(parallel [(set (match_dup 4)
12317                    (neg:P (match_dup 3)))
12318               (set (reg:P CA_REGNO)
12319                    (eq:P (match_dup 3)
12320                          (const_int 0)))])
12321    (parallel [(set (match_dup 0)
12322                    (plus:P (reg:P CA_REGNO)
12323                            (const_int -1)))
12324               (clobber (reg:P CA_REGNO))])]
12326   operands[3] = rs6000_emit_eqne (<MODE>mode,
12327                                   operands[1], operands[2], operands[3]);
12329   if (GET_CODE (operands[4]) == SCRATCH)
12330     operands[4] = gen_reg_rtx (<MODE>mode);
12332   [(set (attr "length")
12333         (if_then_else (match_test "operands[2] == const0_rtx")
12334                       (const_string "8")
12335                       (const_string "12")))])
12337 (define_insn_and_split "*plus_eq_<mode>"
12338   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12339         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12340                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12341                 (match_operand:P 3 "gpc_reg_operand" "r")))
12342    (clobber (match_scratch:P 4 "=r"))
12343    (clobber (match_scratch:P 5 "=r"))
12344    (clobber (reg:P CA_REGNO))]
12345   ""
12346   "#"
12347   ""
12348   [(parallel [(set (match_dup 5)
12349                    (neg:P (match_dup 4)))
12350               (set (reg:P CA_REGNO)
12351                    (eq:P (match_dup 4)
12352                          (const_int 0)))])
12353    (parallel [(set (match_dup 0)
12354                    (plus:P (match_dup 3)
12355                            (reg:P CA_REGNO)))
12356               (clobber (reg:P CA_REGNO))])]
12358   operands[4] = rs6000_emit_eqne (<MODE>mode,
12359                                   operands[1], operands[2], operands[4]);
12361   if (GET_CODE (operands[5]) == SCRATCH)
12362     operands[5] = gen_reg_rtx (<MODE>mode);
12364   [(set (attr "length")
12365         (if_then_else (match_test "operands[2] == const0_rtx")
12366                       (const_string "8")
12367                       (const_string "12")))])
12369 (define_insn_and_split "*plus_ne_<mode>"
12370   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12371         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12372                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12373                 (match_operand:P 3 "gpc_reg_operand" "r")))
12374    (clobber (match_scratch:P 4 "=r"))
12375    (clobber (match_scratch:P 5 "=r"))
12376    (clobber (reg:P CA_REGNO))]
12377   ""
12378   "#"
12379   ""
12380   [(parallel [(set (match_dup 5)
12381                    (plus:P (match_dup 4)
12382                            (const_int -1)))
12383               (set (reg:P CA_REGNO)
12384                    (ne:P (match_dup 4)
12385                          (const_int 0)))])
12386    (parallel [(set (match_dup 0)
12387                    (plus:P (match_dup 3)
12388                            (reg:P CA_REGNO)))
12389               (clobber (reg:P CA_REGNO))])]
12391   operands[4] = rs6000_emit_eqne (<MODE>mode,
12392                                   operands[1], operands[2], operands[4]);
12394   if (GET_CODE (operands[5]) == SCRATCH)
12395     operands[5] = gen_reg_rtx (<MODE>mode);
12397   [(set (attr "length")
12398         (if_then_else (match_test "operands[2] == const0_rtx")
12399                       (const_string "8")
12400                       (const_string "12")))])
12402 (define_insn_and_split "*minus_eq_<mode>"
12403   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12404         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12405                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12406                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12407    (clobber (match_scratch:P 4 "=r"))
12408    (clobber (match_scratch:P 5 "=r"))
12409    (clobber (reg:P CA_REGNO))]
12410   ""
12411   "#"
12412   ""
12413   [(parallel [(set (match_dup 5)
12414                    (plus:P (match_dup 4)
12415                            (const_int -1)))
12416               (set (reg:P CA_REGNO)
12417                    (ne:P (match_dup 4)
12418                          (const_int 0)))])
12419    (parallel [(set (match_dup 0)
12420                    (plus:P (plus:P (match_dup 3)
12421                                    (reg:P CA_REGNO))
12422                            (const_int -1)))
12423               (clobber (reg:P CA_REGNO))])]
12425   operands[4] = rs6000_emit_eqne (<MODE>mode,
12426                                   operands[1], operands[2], operands[4]);
12428   if (GET_CODE (operands[5]) == SCRATCH)
12429     operands[5] = gen_reg_rtx (<MODE>mode);
12431   [(set (attr "length")
12432         (if_then_else (match_test "operands[2] == const0_rtx")
12433                       (const_string "8")
12434                       (const_string "12")))])
12436 (define_insn_and_split "*minus_ne_<mode>"
12437   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12438         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12439                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12440                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12441    (clobber (match_scratch:P 4 "=r"))
12442    (clobber (match_scratch:P 5 "=r"))
12443    (clobber (reg:P CA_REGNO))]
12444   ""
12445   "#"
12446   ""
12447   [(parallel [(set (match_dup 5)
12448                    (neg:P (match_dup 4)))
12449               (set (reg:P CA_REGNO)
12450                    (eq:P (match_dup 4)
12451                          (const_int 0)))])
12452    (parallel [(set (match_dup 0)
12453                    (plus:P (plus:P (match_dup 3)
12454                                    (reg:P CA_REGNO))
12455                            (const_int -1)))
12456               (clobber (reg:P CA_REGNO))])]
12458   operands[4] = rs6000_emit_eqne (<MODE>mode,
12459                                   operands[1], operands[2], operands[4]);
12461   if (GET_CODE (operands[5]) == SCRATCH)
12462     operands[5] = gen_reg_rtx (<MODE>mode);
12464   [(set (attr "length")
12465         (if_then_else (match_test "operands[2] == const0_rtx")
12466                       (const_string "8")
12467                       (const_string "12")))])
12469 (define_insn_and_split "*eqsi3_ext<mode>"
12470   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12471         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12472                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12473    (clobber (match_scratch:SI 3 "=r"))
12474    (clobber (match_scratch:SI 4 "=r"))]
12475   ""
12476   "#"
12477   ""
12478   [(set (match_dup 4)
12479         (clz:SI (match_dup 3)))
12480    (set (match_dup 0)
12481         (zero_extend:EXTSI
12482           (lshiftrt:SI (match_dup 4)
12483                        (const_int 5))))]
12485   operands[3] = rs6000_emit_eqne (SImode,
12486                                   operands[1], operands[2], operands[3]);
12488   if (GET_CODE (operands[4]) == SCRATCH)
12489     operands[4] = gen_reg_rtx (SImode);
12491   [(set (attr "length")
12492         (if_then_else (match_test "operands[2] == const0_rtx")
12493                       (const_string "8")
12494                       (const_string "12")))])
12496 (define_insn_and_split "*nesi3_ext<mode>"
12497   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12498         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12499                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12500    (clobber (match_scratch:SI 3 "=r"))
12501    (clobber (match_scratch:SI 4 "=r"))
12502    (clobber (match_scratch:EXTSI 5 "=r"))]
12503   ""
12504   "#"
12505   ""
12506   [(set (match_dup 4)
12507         (clz:SI (match_dup 3)))
12508    (set (match_dup 5)
12509         (zero_extend:EXTSI
12510           (lshiftrt:SI (match_dup 4)
12511                        (const_int 5))))
12512    (set (match_dup 0)
12513         (xor:EXTSI (match_dup 5)
12514                    (const_int 1)))]
12516   operands[3] = rs6000_emit_eqne (SImode,
12517                                   operands[1], operands[2], operands[3]);
12519   if (GET_CODE (operands[4]) == SCRATCH)
12520     operands[4] = gen_reg_rtx (SImode);
12521   if (GET_CODE (operands[5]) == SCRATCH)
12522     operands[5] = gen_reg_rtx (<MODE>mode);
12524   [(set (attr "length")
12525         (if_then_else (match_test "operands[2] == const0_rtx")
12526                       (const_string "12")
12527                       (const_string "16")))])
12529 ;; Define both directions of branch and return.  If we need a reload
12530 ;; register, we'd rather use CR0 since it is much easier to copy a
12531 ;; register CC value to there.
12533 (define_insn ""
12534   [(set (pc)
12535         (if_then_else (match_operator 1 "branch_comparison_operator"
12536                                       [(match_operand 2
12537                                                       "cc_reg_operand" "y")
12538                                        (const_int 0)])
12539                       (label_ref (match_operand 0 "" ""))
12540                       (pc)))]
12541   ""
12542   "*
12544   return output_cbranch (operands[1], \"%l0\", 0, insn);
12546   [(set_attr "type" "branch")])
12548 (define_insn ""
12549   [(set (pc)
12550         (if_then_else (match_operator 0 "branch_comparison_operator"
12551                                       [(match_operand 1
12552                                                       "cc_reg_operand" "y")
12553                                        (const_int 0)])
12554                       (any_return)
12555                       (pc)))]
12556   "<return_pred>"
12557   "*
12559   return output_cbranch (operands[0], NULL, 0, insn);
12561   [(set_attr "type" "jmpreg")
12562    (set_attr "length" "4")])
12564 (define_insn ""
12565   [(set (pc)
12566         (if_then_else (match_operator 1 "branch_comparison_operator"
12567                                       [(match_operand 2
12568                                                       "cc_reg_operand" "y")
12569                                        (const_int 0)])
12570                       (pc)
12571                       (label_ref (match_operand 0 "" ""))))]
12572   ""
12573   "*
12575   return output_cbranch (operands[1], \"%l0\", 1, insn);
12577   [(set_attr "type" "branch")])
12579 (define_insn ""
12580   [(set (pc)
12581         (if_then_else (match_operator 0 "branch_comparison_operator"
12582                                       [(match_operand 1
12583                                                       "cc_reg_operand" "y")
12584                                        (const_int 0)])
12585                       (pc)
12586                       (any_return)))]
12587   "<return_pred>"
12588   "*
12590   return output_cbranch (operands[0], NULL, 1, insn);
12592   [(set_attr "type" "jmpreg")
12593    (set_attr "length" "4")])
12595 ;; Logic on condition register values.
12597 ; This pattern matches things like
12598 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12599 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12600 ;                                  (const_int 1)))
12601 ; which are generated by the branch logic.
12602 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12604 (define_insn "*cceq_ior_compare"
12605   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12606         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12607                         [(match_operator:SI 2
12608                                       "branch_positive_comparison_operator"
12609                                       [(match_operand 3
12610                                                       "cc_reg_operand" "y,y")
12611                                        (const_int 0)])
12612                          (match_operator:SI 4
12613                                       "branch_positive_comparison_operator"
12614                                       [(match_operand 5
12615                                                       "cc_reg_operand" "0,y")
12616                                        (const_int 0)])])
12617                       (const_int 1)))]
12618   ""
12619   "cr%q1 %E0,%j2,%j4"
12620   [(set_attr "type" "cr_logical,delayed_cr")])
12622 ; Why is the constant -1 here, but 1 in the previous pattern?
12623 ; Because ~1 has all but the low bit set.
12624 (define_insn ""
12625   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12626         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12627                         [(not:SI (match_operator:SI 2
12628                                       "branch_positive_comparison_operator"
12629                                       [(match_operand 3
12630                                                       "cc_reg_operand" "y,y")
12631                                        (const_int 0)]))
12632                          (match_operator:SI 4
12633                                 "branch_positive_comparison_operator"
12634                                 [(match_operand 5
12635                                                 "cc_reg_operand" "0,y")
12636                                  (const_int 0)])])
12637                       (const_int -1)))]
12638   ""
12639   "cr%q1 %E0,%j2,%j4"
12640   [(set_attr "type" "cr_logical,delayed_cr")])
12642 (define_insn "*cceq_rev_compare"
12643   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12644         (compare:CCEQ (match_operator:SI 1
12645                                       "branch_positive_comparison_operator"
12646                                       [(match_operand 2
12647                                                       "cc_reg_operand" "0,y")
12648                                        (const_int 0)])
12649                       (const_int 0)))]
12650   ""
12651   "crnot %E0,%j1"
12652   [(set_attr "type" "cr_logical,delayed_cr")])
12654 ;; If we are comparing the result of two comparisons, this can be done
12655 ;; using creqv or crxor.
12657 (define_insn_and_split ""
12658   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12659         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12660                               [(match_operand 2 "cc_reg_operand" "y")
12661                                (const_int 0)])
12662                       (match_operator 3 "branch_comparison_operator"
12663                               [(match_operand 4 "cc_reg_operand" "y")
12664                                (const_int 0)])))]
12665   ""
12666   "#"
12667   ""
12668   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12669                                     (match_dup 5)))]
12670   "
12672   int positive_1, positive_2;
12674   positive_1 = branch_positive_comparison_operator (operands[1],
12675                                                     GET_MODE (operands[1]));
12676   positive_2 = branch_positive_comparison_operator (operands[3],
12677                                                     GET_MODE (operands[3]));
12679   if (! positive_1)
12680     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12681                                                             GET_CODE (operands[1])),
12682                                   SImode,
12683                                   operands[2], const0_rtx);
12684   else if (GET_MODE (operands[1]) != SImode)
12685     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12686                                   operands[2], const0_rtx);
12688   if (! positive_2)
12689     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12690                                                             GET_CODE (operands[3])),
12691                                   SImode,
12692                                   operands[4], const0_rtx);
12693   else if (GET_MODE (operands[3]) != SImode)
12694     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12695                                   operands[4], const0_rtx);
12697   if (positive_1 == positive_2)
12698     {
12699       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12700       operands[5] = constm1_rtx;
12701     }
12702   else
12703     {
12704       operands[5] = const1_rtx;
12705     }
12708 ;; Unconditional branch and return.
12710 (define_insn "jump"
12711   [(set (pc)
12712         (label_ref (match_operand 0 "" "")))]
12713   ""
12714   "b %l0"
12715   [(set_attr "type" "branch")])
12717 (define_insn "<return_str>return"
12718   [(any_return)]
12719   "<return_pred>"
12720   "blr"
12721   [(set_attr "type" "jmpreg")])
12723 (define_expand "indirect_jump"
12724   [(set (pc) (match_operand 0 "register_operand" ""))])
12726 (define_insn "*indirect_jump<mode>"
12727   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12728   ""
12729   "@
12730    bctr
12731    blr"
12732   [(set_attr "type" "jmpreg")])
12734 ;; Table jump for switch statements:
12735 (define_expand "tablejump"
12736   [(use (match_operand 0 "" ""))
12737    (use (label_ref (match_operand 1 "" "")))]
12738   ""
12739   "
12741   if (TARGET_32BIT)
12742     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12743   else
12744     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12745   DONE;
12748 (define_expand "tablejumpsi"
12749   [(set (match_dup 3)
12750         (plus:SI (match_operand:SI 0 "" "")
12751                  (match_dup 2)))
12752    (parallel [(set (pc) (match_dup 3))
12753               (use (label_ref (match_operand 1 "" "")))])]
12754   "TARGET_32BIT"
12755   "
12756 { operands[0] = force_reg (SImode, operands[0]);
12757   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12758   operands[3] = gen_reg_rtx (SImode);
12761 (define_expand "tablejumpdi"
12762   [(set (match_dup 4)
12763         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12764    (set (match_dup 3)
12765         (plus:DI (match_dup 4)
12766                  (match_dup 2)))
12767    (parallel [(set (pc) (match_dup 3))
12768               (use (label_ref (match_operand 1 "" "")))])]
12769   "TARGET_64BIT"
12770   "
12771 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12772   operands[3] = gen_reg_rtx (DImode);
12773   operands[4] = gen_reg_rtx (DImode);
12776 (define_insn "*tablejump<mode>_internal1"
12777   [(set (pc)
12778         (match_operand:P 0 "register_operand" "c,*l"))
12779    (use (label_ref (match_operand 1 "" "")))]
12780   ""
12781   "@
12782    bctr
12783    blr"
12784   [(set_attr "type" "jmpreg")])
12786 (define_insn "nop"
12787   [(unspec [(const_int 0)] UNSPEC_NOP)]
12788   ""
12789   "nop")
12791 (define_insn "group_ending_nop"
12792   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12793   ""
12794   "*
12796   if (rs6000_cpu_attr == CPU_POWER6)
12797     return \"ori 1,1,0\";
12798   return \"ori 2,2,0\";
12801 ;; Define the subtract-one-and-jump insns, starting with the template
12802 ;; so loop.c knows what to generate.
12804 (define_expand "doloop_end"
12805   [(use (match_operand 0 "" ""))        ; loop pseudo
12806    (use (match_operand 1 "" ""))]       ; label
12807   ""
12808   "
12810   if (TARGET_64BIT)
12811     {
12812       if (GET_MODE (operands[0]) != DImode)
12813         FAIL;
12814       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12815     }
12816   else
12817     {
12818       if (GET_MODE (operands[0]) != SImode)
12819         FAIL;
12820       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12821     }
12822   DONE;
12825 (define_expand "ctr<mode>"
12826   [(parallel [(set (pc)
12827                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12828                                      (const_int 1))
12829                                  (label_ref (match_operand 1 "" ""))
12830                                  (pc)))
12831               (set (match_dup 0)
12832                    (plus:P (match_dup 0)
12833                             (const_int -1)))
12834               (clobber (match_scratch:CC 2 ""))
12835               (clobber (match_scratch:P 3 ""))])]
12836   ""
12837   "")
12839 ;; We need to be able to do this for any operand, including MEM, or we
12840 ;; will cause reload to blow up since we don't allow output reloads on
12841 ;; JUMP_INSNs.
12842 ;; For the length attribute to be calculated correctly, the
12843 ;; label MUST be operand 0.
12844 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12845 ;; the ctr<mode> insns.
12847 (define_insn "ctr<mode>_internal1"
12848   [(set (pc)
12849         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12850                           (const_int 1))
12851                       (label_ref (match_operand 0 "" ""))
12852                       (pc)))
12853    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12854         (plus:P (match_dup 1)
12855                  (const_int -1)))
12856    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12857    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12858   ""
12859   "*
12861   if (which_alternative != 0)
12862     return \"#\";
12863   else if (get_attr_length (insn) == 4)
12864     return \"bdnz %l0\";
12865   else
12866     return \"bdz $+8\;b %l0\";
12868   [(set_attr "type" "branch")
12869    (set_attr "length" "*,16,20,20")])
12871 (define_insn "ctr<mode>_internal2"
12872   [(set (pc)
12873         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12874                           (const_int 1))
12875                       (pc)
12876                       (label_ref (match_operand 0 "" ""))))
12877    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12878         (plus:P (match_dup 1)
12879                  (const_int -1)))
12880    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12881    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12882   ""
12883   "*
12885   if (which_alternative != 0)
12886     return \"#\";
12887   else if (get_attr_length (insn) == 4)
12888     return \"bdz %l0\";
12889   else
12890     return \"bdnz $+8\;b %l0\";
12892   [(set_attr "type" "branch")
12893    (set_attr "length" "*,16,20,20")])
12895 ;; Similar but use EQ
12897 (define_insn "ctr<mode>_internal3"
12898   [(set (pc)
12899         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12900                           (const_int 1))
12901                       (label_ref (match_operand 0 "" ""))
12902                       (pc)))
12903    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12904         (plus:P (match_dup 1)
12905                  (const_int -1)))
12906    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12907    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12908   ""
12909   "*
12911   if (which_alternative != 0)
12912     return \"#\";
12913   else if (get_attr_length (insn) == 4)
12914     return \"bdz %l0\";
12915   else
12916     return \"bdnz $+8\;b %l0\";
12918   [(set_attr "type" "branch")
12919    (set_attr "length" "*,16,20,20")])
12921 (define_insn "ctr<mode>_internal4"
12922   [(set (pc)
12923         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12924                           (const_int 1))
12925                       (pc)
12926                       (label_ref (match_operand 0 "" ""))))
12927    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12928         (plus:P (match_dup 1)
12929                  (const_int -1)))
12930    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12931    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12932   ""
12933   "*
12935   if (which_alternative != 0)
12936     return \"#\";
12937   else if (get_attr_length (insn) == 4)
12938     return \"bdnz %l0\";
12939   else
12940     return \"bdz $+8\;b %l0\";
12942   [(set_attr "type" "branch")
12943    (set_attr "length" "*,16,20,20")])
12945 ;; Now the splitters if we could not allocate the CTR register
12947 (define_split
12948   [(set (pc)
12949         (if_then_else (match_operator 2 "comparison_operator"
12950                                       [(match_operand:P 1 "gpc_reg_operand" "")
12951                                        (const_int 1)])
12952                       (match_operand 5 "" "")
12953                       (match_operand 6 "" "")))
12954    (set (match_operand:P 0 "int_reg_operand" "")
12955         (plus:P (match_dup 1) (const_int -1)))
12956    (clobber (match_scratch:CC 3 ""))
12957    (clobber (match_scratch:P 4 ""))]
12958   "reload_completed"
12959   [(set (match_dup 3)
12960         (compare:CC (match_dup 1)
12961                     (const_int 1)))
12962    (set (match_dup 0)
12963         (plus:P (match_dup 1)
12964                 (const_int -1)))
12965    (set (pc) (if_then_else (match_dup 7)
12966                            (match_dup 5)
12967                            (match_dup 6)))]
12968   "
12969 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12970                                 operands[3], const0_rtx); }")
12972 (define_split
12973   [(set (pc)
12974         (if_then_else (match_operator 2 "comparison_operator"
12975                                       [(match_operand:P 1 "gpc_reg_operand" "")
12976                                        (const_int 1)])
12977                       (match_operand 5 "" "")
12978                       (match_operand 6 "" "")))
12979    (set (match_operand:P 0 "nonimmediate_operand" "")
12980         (plus:P (match_dup 1) (const_int -1)))
12981    (clobber (match_scratch:CC 3 ""))
12982    (clobber (match_scratch:P 4 ""))]
12983   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12984   [(set (match_dup 3)
12985         (compare:CC (match_dup 1)
12986                     (const_int 1)))
12987    (set (match_dup 4)
12988         (plus:P (match_dup 1)
12989                 (const_int -1)))
12990    (set (match_dup 0)
12991         (match_dup 4))
12992    (set (pc) (if_then_else (match_dup 7)
12993                            (match_dup 5)
12994                            (match_dup 6)))]
12995   "
12996 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12997                                 operands[3], const0_rtx); }")
12999 (define_insn "trap"
13000   [(trap_if (const_int 1) (const_int 0))]
13001   ""
13002   "trap"
13003   [(set_attr "type" "trap")])
13005 (define_expand "ctrap<mode>4"
13006   [(trap_if (match_operator 0 "ordered_comparison_operator"
13007                             [(match_operand:GPR 1 "register_operand")
13008                              (match_operand:GPR 2 "reg_or_short_operand")])
13009             (match_operand 3 "zero_constant" ""))]
13010   ""
13011   "")
13013 (define_insn ""
13014   [(trap_if (match_operator 0 "ordered_comparison_operator"
13015                             [(match_operand:GPR 1 "register_operand" "r")
13016                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13017             (const_int 0))]
13018   ""
13019   "t<wd>%V0%I2 %1,%2"
13020   [(set_attr "type" "trap")])
13022 ;; Insns related to generating the function prologue and epilogue.
13024 (define_expand "prologue"
13025   [(use (const_int 0))]
13026   ""
13028   rs6000_emit_prologue ();
13029   if (!TARGET_SCHED_PROLOG)
13030     emit_insn (gen_blockage ());
13031   DONE;
13034 (define_insn "*movesi_from_cr_one"
13035   [(match_parallel 0 "mfcr_operation"
13036                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13037                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13038                                      (match_operand 3 "immediate_operand" "n")]
13039                           UNSPEC_MOVESI_FROM_CR))])]
13040   "TARGET_MFCRF"
13041   "*
13043   int mask = 0;
13044   int i;
13045   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13046   {
13047     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13048     operands[4] = GEN_INT (mask);
13049     output_asm_insn (\"mfcr %1,%4\", operands);
13050   }
13051   return \"\";
13053   [(set_attr "type" "mfcrf")])
13055 (define_insn "movesi_from_cr"
13056   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13057         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13058                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13059                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13060                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13061                    UNSPEC_MOVESI_FROM_CR))]
13062   ""
13063   "mfcr %0"
13064   [(set_attr "type" "mfcr")])
13066 (define_insn "*crsave"
13067   [(match_parallel 0 "crsave_operation"
13068                    [(set (match_operand:SI 1 "memory_operand" "=m")
13069                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13070   ""
13071   "stw %2,%1"
13072   [(set_attr "type" "store")])
13074 (define_insn "*stmw"
13075   [(match_parallel 0 "stmw_operation"
13076                    [(set (match_operand:SI 1 "memory_operand" "=m")
13077                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13078   "TARGET_MULTIPLE"
13079   "stmw %2,%1"
13080   [(set_attr "type" "store")
13081    (set_attr "update" "yes")
13082    (set_attr "indexed" "yes")])
13084 ; The following comment applies to:
13085 ;     save_gpregs_*
13086 ;     save_fpregs_*
13087 ;     restore_gpregs*
13088 ;     return_and_restore_gpregs*
13089 ;     return_and_restore_fpregs*
13090 ;     return_and_restore_fpregs_aix*
13092 ; The out-of-line save / restore functions expects one input argument.
13093 ; Since those are not standard call_insn's, we must avoid using
13094 ; MATCH_OPERAND for that argument. That way the register rename
13095 ; optimization will not try to rename this register.
13096 ; Each pattern is repeated for each possible register number used in 
13097 ; various ABIs (r11, r1, and for some functions r12)
13099 (define_insn "*save_gpregs_<mode>_r11"
13100   [(match_parallel 0 "any_parallel_operand"
13101                    [(clobber (reg:P LR_REGNO))
13102                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13103                     (use (reg:P 11))
13104                     (set (match_operand:P 2 "memory_operand" "=m")
13105                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13106   ""
13107   "bl %1"
13108   [(set_attr "type" "branch")
13109    (set_attr "length" "4")])
13111 (define_insn "*save_gpregs_<mode>_r12"
13112   [(match_parallel 0 "any_parallel_operand"
13113                    [(clobber (reg:P LR_REGNO))
13114                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13115                     (use (reg:P 12))
13116                     (set (match_operand:P 2 "memory_operand" "=m")
13117                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13118   ""
13119   "bl %1"
13120   [(set_attr "type" "branch")
13121    (set_attr "length" "4")])
13123 (define_insn "*save_gpregs_<mode>_r1"
13124   [(match_parallel 0 "any_parallel_operand"
13125                    [(clobber (reg:P LR_REGNO))
13126                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13127                     (use (reg:P 1))
13128                     (set (match_operand:P 2 "memory_operand" "=m")
13129                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13130   ""
13131   "bl %1"
13132   [(set_attr "type" "branch")
13133    (set_attr "length" "4")])
13135 (define_insn "*save_fpregs_<mode>_r11"
13136   [(match_parallel 0 "any_parallel_operand"
13137                    [(clobber (reg:P LR_REGNO))
13138                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13139                     (use (reg:P 11))
13140                     (set (match_operand:DF 2 "memory_operand" "=m")
13141                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13142   ""
13143   "bl %1"
13144   [(set_attr "type" "branch")
13145    (set_attr "length" "4")])
13147 (define_insn "*save_fpregs_<mode>_r12"
13148   [(match_parallel 0 "any_parallel_operand"
13149                    [(clobber (reg:P LR_REGNO))
13150                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13151                     (use (reg:P 12))
13152                     (set (match_operand:DF 2 "memory_operand" "=m")
13153                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13154   ""
13155   "bl %1"
13156   [(set_attr "type" "branch")
13157    (set_attr "length" "4")])
13159 (define_insn "*save_fpregs_<mode>_r1"
13160   [(match_parallel 0 "any_parallel_operand"
13161                    [(clobber (reg:P LR_REGNO))
13162                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13163                     (use (reg:P 1))
13164                     (set (match_operand:DF 2 "memory_operand" "=m")
13165                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13166   ""
13167   "bl %1"
13168   [(set_attr "type" "branch")
13169    (set_attr "length" "4")])
13171 ; This is to explain that changes to the stack pointer should
13172 ; not be moved over loads from or stores to stack memory.
13173 (define_insn "stack_tie"
13174   [(match_parallel 0 "tie_operand"
13175                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13176   ""
13177   ""
13178   [(set_attr "length" "0")])
13180 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13181 ; stay behind all restores from the stack, it cannot be reordered to before
13182 ; one.  See PR77687.  This insn is an add or mr, and a stack_tie on the
13183 ; operands of that.
13184 (define_insn "stack_restore_tie"
13185   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13186         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13187                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13188    (set (mem:BLK (match_dup 0)) (const_int 0))
13189    (set (mem:BLK (match_dup 1)) (const_int 0))]
13190   "TARGET_32BIT"
13191   "@
13192    mr %0,%1
13193    add%I2 %0,%1,%2"
13194   [(set_attr "type" "*,add")])
13196 (define_expand "epilogue"
13197   [(use (const_int 0))]
13198   ""
13200   if (!TARGET_SCHED_PROLOG)
13201     emit_insn (gen_blockage ());
13202   rs6000_emit_epilogue (FALSE);
13203   DONE;
13206 ; On some processors, doing the mtcrf one CC register at a time is
13207 ; faster (like on the 604e).  On others, doing them all at once is
13208 ; faster; for instance, on the 601 and 750.
13210 (define_expand "movsi_to_cr_one"
13211   [(set (match_operand:CC 0 "cc_reg_operand" "")
13212         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13213                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13214   ""
13215   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13217 (define_insn "*movsi_to_cr"
13218   [(match_parallel 0 "mtcrf_operation"
13219                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13220                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13221                                      (match_operand 3 "immediate_operand" "n")]
13222                                     UNSPEC_MOVESI_TO_CR))])]
13223  ""
13224  "*
13226   int mask = 0;
13227   int i;
13228   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13229     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13230   operands[4] = GEN_INT (mask);
13231   return \"mtcrf %4,%2\";
13233   [(set_attr "type" "mtcr")])
13235 (define_insn "*mtcrfsi"
13236   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13237         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13238                     (match_operand 2 "immediate_operand" "n")]
13239                    UNSPEC_MOVESI_TO_CR))]
13240   "GET_CODE (operands[0]) == REG
13241    && CR_REGNO_P (REGNO (operands[0]))
13242    && GET_CODE (operands[2]) == CONST_INT
13243    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13244   "mtcrf %R0,%1"
13245   [(set_attr "type" "mtcr")])
13247 ; The load-multiple instructions have similar properties.
13248 ; Note that "load_multiple" is a name known to the machine-independent
13249 ; code that actually corresponds to the PowerPC load-string.
13251 (define_insn "*lmw"
13252   [(match_parallel 0 "lmw_operation"
13253                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13254                          (match_operand:SI 2 "memory_operand" "m"))])]
13255   "TARGET_MULTIPLE"
13256   "lmw %1,%2"
13257   [(set_attr "type" "load")
13258    (set_attr "update" "yes")
13259    (set_attr "indexed" "yes")
13260    (set_attr "cell_micro" "always")])
13262 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13263 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13265 ; The following comment applies to:
13266 ;     save_gpregs_*
13267 ;     save_fpregs_*
13268 ;     restore_gpregs*
13269 ;     return_and_restore_gpregs*
13270 ;     return_and_restore_fpregs*
13271 ;     return_and_restore_fpregs_aix*
13273 ; The out-of-line save / restore functions expects one input argument.
13274 ; Since those are not standard call_insn's, we must avoid using
13275 ; MATCH_OPERAND for that argument. That way the register rename
13276 ; optimization will not try to rename this register.
13277 ; Each pattern is repeated for each possible register number used in 
13278 ; various ABIs (r11, r1, and for some functions r12)
13280 (define_insn "*restore_gpregs_<mode>_r11"
13281  [(match_parallel 0 "any_parallel_operand"
13282                   [(clobber (reg:P LR_REGNO))
13283                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13284                    (use (reg:P 11))
13285                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13286                         (match_operand:P 3 "memory_operand" "m"))])]
13287  ""
13288  "bl %1"
13289  [(set_attr "type" "branch")
13290   (set_attr "length" "4")])
13292 (define_insn "*restore_gpregs_<mode>_r12"
13293  [(match_parallel 0 "any_parallel_operand"
13294                   [(clobber (reg:P LR_REGNO))
13295                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13296                    (use (reg:P 12))
13297                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13298                         (match_operand:P 3 "memory_operand" "m"))])]
13299  ""
13300  "bl %1"
13301  [(set_attr "type" "branch")
13302   (set_attr "length" "4")])
13304 (define_insn "*restore_gpregs_<mode>_r1"
13305  [(match_parallel 0 "any_parallel_operand"
13306                   [(clobber (reg:P LR_REGNO))
13307                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13308                    (use (reg:P 1))
13309                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13310                         (match_operand:P 3 "memory_operand" "m"))])]
13311  ""
13312  "bl %1"
13313  [(set_attr "type" "branch")
13314   (set_attr "length" "4")])
13316 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13317  [(match_parallel 0 "any_parallel_operand"
13318                   [(return)
13319                    (clobber (reg:P LR_REGNO))
13320                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13321                    (use (reg:P 11))
13322                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13323                         (match_operand:P 3 "memory_operand" "m"))])]
13324  ""
13325  "b %1"
13326  [(set_attr "type" "branch")
13327   (set_attr "length" "4")])
13329 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13330  [(match_parallel 0 "any_parallel_operand"
13331                   [(return)
13332                    (clobber (reg:P LR_REGNO))
13333                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13334                    (use (reg:P 12))
13335                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13336                         (match_operand:P 3 "memory_operand" "m"))])]
13337  ""
13338  "b %1"
13339  [(set_attr "type" "branch")
13340   (set_attr "length" "4")])
13342 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13343  [(match_parallel 0 "any_parallel_operand"
13344                   [(return)
13345                    (clobber (reg:P LR_REGNO))
13346                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13347                    (use (reg:P 1))
13348                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13349                         (match_operand:P 3 "memory_operand" "m"))])]
13350  ""
13351  "b %1"
13352  [(set_attr "type" "branch")
13353   (set_attr "length" "4")])
13355 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13356  [(match_parallel 0 "any_parallel_operand"
13357                   [(return)
13358                    (clobber (reg:P LR_REGNO))
13359                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13360                    (use (reg:P 11))
13361                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13362                         (match_operand:DF 3 "memory_operand" "m"))])]
13363  ""
13364  "b %1"
13365  [(set_attr "type" "branch")
13366   (set_attr "length" "4")])
13368 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13369  [(match_parallel 0 "any_parallel_operand"
13370                   [(return)
13371                    (clobber (reg:P LR_REGNO))
13372                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13373                    (use (reg:P 12))
13374                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13375                         (match_operand:DF 3 "memory_operand" "m"))])]
13376  ""
13377  "b %1"
13378  [(set_attr "type" "branch")
13379   (set_attr "length" "4")])
13381 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13382  [(match_parallel 0 "any_parallel_operand"
13383                   [(return)
13384                    (clobber (reg:P LR_REGNO))
13385                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13386                    (use (reg:P 1))
13387                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13388                         (match_operand:DF 3 "memory_operand" "m"))])]
13389  ""
13390  "b %1"
13391  [(set_attr "type" "branch")
13392   (set_attr "length" "4")])
13394 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13395  [(match_parallel 0 "any_parallel_operand"
13396                   [(return)
13397                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13398                    (use (reg:P 11))
13399                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13400                         (match_operand:DF 3 "memory_operand" "m"))])]
13401  ""
13402  "b %1"
13403  [(set_attr "type" "branch")
13404   (set_attr "length" "4")])
13406 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13407  [(match_parallel 0 "any_parallel_operand"
13408                   [(return)
13409                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13410                    (use (reg:P 1))
13411                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13412                         (match_operand:DF 3 "memory_operand" "m"))])]
13413  ""
13414  "b %1"
13415  [(set_attr "type" "branch")
13416   (set_attr "length" "4")])
13418 ; This is used in compiling the unwind routines.
13419 (define_expand "eh_return"
13420   [(use (match_operand 0 "general_operand" ""))]
13421   ""
13422   "
13424   if (TARGET_32BIT)
13425     emit_insn (gen_eh_set_lr_si (operands[0]));
13426   else
13427     emit_insn (gen_eh_set_lr_di (operands[0]));
13428   DONE;
13431 ; We can't expand this before we know where the link register is stored.
13432 (define_insn "eh_set_lr_<mode>"
13433   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13434                     UNSPECV_EH_RR)
13435    (clobber (match_scratch:P 1 "=&b"))]
13436   ""
13437   "#")
13439 (define_split
13440   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13441    (clobber (match_scratch 1 ""))]
13442   "reload_completed"
13443   [(const_int 0)]
13444   "
13446   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13447   DONE;
13450 (define_insn "prefetch"
13451   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13452              (match_operand:SI 1 "const_int_operand" "n")
13453              (match_operand:SI 2 "const_int_operand" "n"))]
13454   ""
13455   "*
13457   if (GET_CODE (operands[0]) == REG)
13458     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13459   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13461   [(set_attr "type" "load")])
13463 ;; Handle -fsplit-stack.
13465 (define_expand "split_stack_prologue"
13466   [(const_int 0)]
13467   ""
13469   rs6000_expand_split_stack_prologue ();
13470   DONE;
13473 (define_expand "load_split_stack_limit"
13474   [(set (match_operand 0)
13475         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13476   ""
13478   emit_insn (gen_rtx_SET (operands[0],
13479                           gen_rtx_UNSPEC (Pmode,
13480                                           gen_rtvec (1, const0_rtx),
13481                                           UNSPEC_STACK_CHECK)));
13482   DONE;
13485 (define_insn "load_split_stack_limit_di"
13486   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13487         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13488   "TARGET_64BIT"
13489   "ld %0,-0x7040(13)"
13490   [(set_attr "type" "load")
13491    (set_attr "update" "no")
13492    (set_attr "indexed" "no")])
13494 (define_insn "load_split_stack_limit_si"
13495   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13496         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13497   "!TARGET_64BIT"
13498   "lwz %0,-0x7020(2)"
13499   [(set_attr "type" "load")
13500    (set_attr "update" "no")
13501    (set_attr "indexed" "no")])
13503 ;; A return instruction which the middle-end doesn't see.
13504 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13505 ;; after the call to __morestack.
13506 (define_insn "split_stack_return"
13507   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13508   ""
13509   "blr"
13510   [(set_attr "type" "jmpreg")])
13512 ;; If there are operand 0 bytes available on the stack, jump to
13513 ;; operand 1.
13514 (define_expand "split_stack_space_check"
13515   [(set (match_dup 2)
13516         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13517    (set (match_dup 3)
13518         (minus (reg STACK_POINTER_REGNUM)
13519                (match_operand 0)))
13520    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13521    (set (pc) (if_then_else
13522               (geu (match_dup 4) (const_int 0))
13523               (label_ref (match_operand 1))
13524               (pc)))]
13525   ""
13527   rs6000_split_stack_space_check (operands[0], operands[1]);
13528   DONE;
13531 (define_insn "bpermd_<mode>"
13532   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13533         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13534                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13535   "TARGET_POPCNTD"
13536   "bpermd %0,%1,%2"
13537   [(set_attr "type" "popcnt")])
13540 ;; Builtin fma support.  Handle 
13541 ;; Note that the conditions for expansion are in the FMA_F iterator.
13543 (define_expand "fma<mode>4"
13544   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13545         (fma:FMA_F
13546           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13547           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13548           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13549   ""
13550   "")
13552 (define_insn "*fma<mode>4_fpr"
13553   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13554         (fma:SFDF
13555           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13556           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13557           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13558   "TARGET_<MODE>_FPR"
13559   "@
13560    fmadd<Ftrad> %0,%1,%2,%3
13561    xsmadda<Fvsx> %x0,%x1,%x2
13562    xsmaddm<Fvsx> %x0,%x1,%x3"
13563   [(set_attr "type" "fp")
13564    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13566 ; Altivec only has fma and nfms.
13567 (define_expand "fms<mode>4"
13568   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13569         (fma:FMA_F
13570           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13571           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13572           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13573   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13574   "")
13576 (define_insn "*fms<mode>4_fpr"
13577   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13578         (fma:SFDF
13579          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13580          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13581          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13582   "TARGET_<MODE>_FPR"
13583   "@
13584    fmsub<Ftrad> %0,%1,%2,%3
13585    xsmsuba<Fvsx> %x0,%x1,%x2
13586    xsmsubm<Fvsx> %x0,%x1,%x3"
13587   [(set_attr "type" "fp")
13588    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13590 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13591 (define_expand "fnma<mode>4"
13592   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13593         (neg:FMA_F
13594           (fma:FMA_F
13595             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13596             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13597             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13598   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13599   "")
13601 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13602 (define_expand "fnms<mode>4"
13603   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13604         (neg:FMA_F
13605           (fma:FMA_F
13606             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13607             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13608             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13609   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13610   "")
13612 ; Not an official optab name, but used from builtins.
13613 (define_expand "nfma<mode>4"
13614   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13615         (neg:FMA_F
13616           (fma:FMA_F
13617             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13618             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13619             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13620   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13621   "")
13623 (define_insn "*nfma<mode>4_fpr"
13624   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13625         (neg:SFDF
13626          (fma:SFDF
13627           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13628           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13629           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13630   "TARGET_<MODE>_FPR"
13631   "@
13632    fnmadd<Ftrad> %0,%1,%2,%3
13633    xsnmadda<Fvsx> %x0,%x1,%x2
13634    xsnmaddm<Fvsx> %x0,%x1,%x3"
13635   [(set_attr "type" "fp")
13636    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13638 ; Not an official optab name, but used from builtins.
13639 (define_expand "nfms<mode>4"
13640   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13641         (neg:FMA_F
13642           (fma:FMA_F
13643             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13644             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13645             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13646   ""
13647   "")
13649 (define_insn "*nfmssf4_fpr"
13650   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13651         (neg:SFDF
13652          (fma:SFDF
13653           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13654           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13655           (neg:SFDF
13656            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13657   "TARGET_<MODE>_FPR"
13658   "@
13659    fnmsub<Ftrad> %0,%1,%2,%3
13660    xsnmsuba<Fvsx> %x0,%x1,%x2
13661    xsnmsubm<Fvsx> %x0,%x1,%x3"
13662   [(set_attr "type" "fp")
13663    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13666 (define_expand "rs6000_get_timebase"
13667   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13668   ""
13670   if (TARGET_POWERPC64)
13671     emit_insn (gen_rs6000_mftb_di (operands[0]));
13672   else
13673     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13674   DONE;
13677 (define_insn "rs6000_get_timebase_ppc32"
13678   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13679         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13680    (clobber (match_scratch:SI 1 "=r"))
13681    (clobber (match_scratch:CC 2 "=y"))]
13682   "!TARGET_POWERPC64"
13684   if (WORDS_BIG_ENDIAN)
13685     if (TARGET_MFCRF)
13686       {
13687         return "mfspr %0,269\;"
13688                "mfspr %L0,268\;"
13689                "mfspr %1,269\;"
13690                "cmpw %2,%0,%1\;"
13691                "bne- %2,$-16";
13692       }
13693     else
13694       {
13695         return "mftbu %0\;"
13696                "mftb %L0\;"
13697                "mftbu %1\;"
13698                "cmpw %2,%0,%1\;"
13699                "bne- %2,$-16";
13700       }
13701   else
13702     if (TARGET_MFCRF)
13703       {
13704         return "mfspr %L0,269\;"
13705                "mfspr %0,268\;"
13706                "mfspr %1,269\;"
13707                "cmpw %2,%L0,%1\;"
13708                "bne- %2,$-16";
13709       }
13710     else
13711       {
13712         return "mftbu %L0\;"
13713                "mftb %0\;"
13714                "mftbu %1\;"
13715                "cmpw %2,%L0,%1\;"
13716                "bne- %2,$-16";
13717       }
13719   [(set_attr "length" "20")])
13721 (define_insn "rs6000_mftb_<mode>"
13722   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13723         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13724   ""
13726   if (TARGET_MFCRF)
13727     return "mfspr %0,268";
13728   else
13729     return "mftb %0";
13733 (define_insn "rs6000_mffs"
13734   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13735         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13736   "TARGET_HARD_FLOAT && TARGET_FPRS"
13737   "mffs %0")
13739 (define_insn "rs6000_mtfsf"
13740   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13741                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13742                     UNSPECV_MTFSF)]
13743   "TARGET_HARD_FLOAT && TARGET_FPRS"
13744   "mtfsf %0,%1")
13747 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13748 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13749 ;; register that is being loaded.  The fused ops must be physically adjacent.
13751 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13752 ;; before register allocation, and is meant to reduce the lifetime for the
13753 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13754 ;; to use the register that is being load.  The peephole2 then gathers any
13755 ;; other fused possibilities that it can find after register allocation.  If
13756 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13758 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13759 ;; before register allocation, so that we can avoid allocating a temporary base
13760 ;; register that won't be used, and that we try to load into base registers,
13761 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13762 ;; (addis followed by load) even on power8.
13764 (define_split
13765   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13766         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13767   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13768   [(parallel [(set (match_dup 0) (match_dup 2))
13769               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13770               (use (match_dup 3))
13771               (clobber (scratch:DI))])]
13773   operands[2] = fusion_wrap_memory_address (operands[1]);
13774   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13777 (define_insn "*toc_fusionload_<mode>"
13778   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13779         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13780    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13781    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13782    (clobber (match_scratch:DI 3 "=X,&b"))]
13783   "TARGET_TOC_FUSION_INT"
13785   if (base_reg_operand (operands[0], <MODE>mode))
13786     return emit_fusion_gpr_load (operands[0], operands[1]);
13788   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13790   [(set_attr "type" "load")
13791    (set_attr "length" "8")])
13793 (define_insn "*toc_fusionload_di"
13794   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13795         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13796    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13797    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13798    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13799   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13800    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13802   if (base_reg_operand (operands[0], DImode))
13803     return emit_fusion_gpr_load (operands[0], operands[1]);
13805   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13807   [(set_attr "type" "load")
13808    (set_attr "length" "8")])
13811 ;; Find cases where the addis that feeds into a load instruction is either used
13812 ;; once or is the same as the target register, and replace it with the fusion
13813 ;; insn
13815 (define_peephole2
13816   [(set (match_operand:P 0 "base_reg_operand" "")
13817         (match_operand:P 1 "fusion_gpr_addis" ""))
13818    (set (match_operand:INT1 2 "base_reg_operand" "")
13819         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13820   "TARGET_P8_FUSION
13821    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13822                          operands[3])"
13823   [(const_int 0)]
13825   expand_fusion_gpr_load (operands);
13826   DONE;
13829 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13830 ;; reload)
13832 (define_insn "fusion_gpr_load_<mode>"
13833   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13834         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13835                      UNSPEC_FUSION_GPR))]
13836   "TARGET_P8_FUSION"
13838   return emit_fusion_gpr_load (operands[0], operands[1]);
13840   [(set_attr "type" "load")
13841    (set_attr "length" "8")])
13844 ;; ISA 3.0 (power9) fusion support
13845 ;; Merge addis with floating load/store to FPRs (or GPRs).
13846 (define_peephole2
13847   [(set (match_operand:P 0 "base_reg_operand" "")
13848         (match_operand:P 1 "fusion_gpr_addis" ""))
13849    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13850         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13851   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13852    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13853   [(const_int 0)]
13855   expand_fusion_p9_load (operands);
13856   DONE;
13859 (define_peephole2
13860   [(set (match_operand:P 0 "base_reg_operand" "")
13861         (match_operand:P 1 "fusion_gpr_addis" ""))
13862    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13863         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13864   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13865    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13866    && !rtx_equal_p (operands[0], operands[3])"
13867   [(const_int 0)]
13869   expand_fusion_p9_store (operands);
13870   DONE;
13873 (define_peephole2
13874   [(set (match_operand:SDI 0 "int_reg_operand" "")
13875         (match_operand:SDI 1 "upper16_cint_operand" ""))
13876    (set (match_dup 0)
13877         (ior:SDI (match_dup 0)
13878                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13879   "TARGET_P9_FUSION"
13880   [(set (match_dup 0)
13881         (unspec:SDI [(match_dup 1)
13882                      (match_dup 2)] UNSPEC_FUSION_P9))])
13884 (define_peephole2
13885   [(set (match_operand:SDI 0 "int_reg_operand" "")
13886         (match_operand:SDI 1 "upper16_cint_operand" ""))
13887    (set (match_operand:SDI 2 "int_reg_operand" "")
13888         (ior:SDI (match_dup 0)
13889                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13890   "TARGET_P9_FUSION
13891    && !rtx_equal_p (operands[0], operands[2])
13892    && peep2_reg_dead_p (2, operands[0])"
13893   [(set (match_dup 2)
13894         (unspec:SDI [(match_dup 1)
13895                      (match_dup 3)] UNSPEC_FUSION_P9))])
13897 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13898 ;; reload).  Because we want to eventually have secondary_reload generate
13899 ;; these, they have to have a single alternative that gives the register
13900 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13901 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13902   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13903         (unspec:GPR_FUSION
13904          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13905          UNSPEC_FUSION_P9))
13906    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13907   "TARGET_P9_FUSION"
13909   /* This insn is a secondary reload insn, which cannot have alternatives.
13910      If we are not loading up register 0, use the power8 fusion instead.  */
13911   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13912     return emit_fusion_gpr_load (operands[0], operands[1]);
13914   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13916   [(set_attr "type" "load")
13917    (set_attr "length" "8")])
13919 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13920   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13921         (unspec:GPR_FUSION
13922          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13923          UNSPEC_FUSION_P9))
13924    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13925   "TARGET_P9_FUSION"
13927   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13929   [(set_attr "type" "store")
13930    (set_attr "length" "8")])
13932 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13933   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13934         (unspec:FPR_FUSION
13935          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13936          UNSPEC_FUSION_P9))
13937    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13938   "TARGET_P9_FUSION"
13940   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13942   [(set_attr "type" "fpload")
13943    (set_attr "length" "8")])
13945 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13946   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13947         (unspec:FPR_FUSION
13948          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13949          UNSPEC_FUSION_P9))
13950    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13951   "TARGET_P9_FUSION"
13953   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13955   [(set_attr "type" "fpstore")
13956    (set_attr "length" "8")])
13958 (define_insn "*fusion_p9_<mode>_constant"
13959   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13960         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13961                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13962                     UNSPEC_FUSION_P9))] 
13963   "TARGET_P9_FUSION"
13965   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13966   return "ori %0,%0,%2";
13968   [(set_attr "type" "two")
13969    (set_attr "length" "8")])
13972 ;; Miscellaneous ISA 2.06 (power7) instructions
13973 (define_insn "addg6s"
13974   [(set (match_operand:SI 0 "register_operand" "=r")
13975         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13976                     (match_operand:SI 2 "register_operand" "r")]
13977                    UNSPEC_ADDG6S))]
13978   "TARGET_POPCNTD"
13979   "addg6s %0,%1,%2"
13980   [(set_attr "type" "integer")
13981    (set_attr "length" "4")])
13983 (define_insn "cdtbcd"
13984   [(set (match_operand:SI 0 "register_operand" "=r")
13985         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13986                    UNSPEC_CDTBCD))]
13987   "TARGET_POPCNTD"
13988   "cdtbcd %0,%1"
13989   [(set_attr "type" "integer")
13990    (set_attr "length" "4")])
13992 (define_insn "cbcdtd"
13993   [(set (match_operand:SI 0 "register_operand" "=r")
13994         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13995                    UNSPEC_CBCDTD))]
13996   "TARGET_POPCNTD"
13997   "cbcdtd %0,%1"
13998   [(set_attr "type" "integer")
13999    (set_attr "length" "4")])
14001 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14002                                         UNSPEC_DIVEO
14003                                         UNSPEC_DIVEU
14004                                         UNSPEC_DIVEUO])
14006 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
14007                              (UNSPEC_DIVEO      "eo")
14008                              (UNSPEC_DIVEU      "eu")
14009                              (UNSPEC_DIVEUO     "euo")])
14011 (define_insn "div<div_extend>_<mode>"
14012   [(set (match_operand:GPR 0 "register_operand" "=r")
14013         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14014                      (match_operand:GPR 2 "register_operand" "r")]
14015                     UNSPEC_DIV_EXTEND))]
14016   "TARGET_POPCNTD"
14017   "div<wd><div_extend> %0,%1,%2"
14018   [(set_attr "type" "div")
14019    (set_attr "size" "<bits>")])
14022 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14024 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14025 (define_mode_attr FP128_64 [(TF "DF")
14026                             (IF "DF")
14027                             (TD "DI")
14028                             (KF "DI")])
14030 (define_expand "unpack<mode>"
14031   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14032         (unspec:<FP128_64>
14033          [(match_operand:FMOVE128 1 "register_operand" "")
14034           (match_operand:QI 2 "const_0_to_1_operand" "")]
14035          UNSPEC_UNPACK_128BIT))]
14036   "FLOAT128_2REG_P (<MODE>mode)"
14037   "")
14039 (define_insn_and_split "unpack<mode>_dm"
14040   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14041         (unspec:<FP128_64>
14042          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14043           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14044          UNSPEC_UNPACK_128BIT))]
14045   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14046   "#"
14047   "&& reload_completed"
14048   [(set (match_dup 0) (match_dup 3))]
14050   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14052   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14053     {
14054       emit_note (NOTE_INSN_DELETED);
14055       DONE;
14056     }
14058   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14060   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14061    (set_attr "length" "4")])
14063 (define_insn_and_split "unpack<mode>_nodm"
14064   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14065         (unspec:<FP128_64>
14066          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14067           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14068          UNSPEC_UNPACK_128BIT))]
14069   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14070   "#"
14071   "&& reload_completed"
14072   [(set (match_dup 0) (match_dup 3))]
14074   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14076   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14077     {
14078       emit_note (NOTE_INSN_DELETED);
14079       DONE;
14080     }
14082   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14084   [(set_attr "type" "fp,fpstore")
14085    (set_attr "length" "4")])
14087 (define_insn_and_split "pack<mode>"
14088   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14089         (unspec:FMOVE128
14090          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14091           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14092          UNSPEC_PACK_128BIT))]
14093   "FLOAT128_2REG_P (<MODE>mode)"
14094   "@
14095    fmr %L0,%2
14096    #"
14097   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14098   [(set (match_dup 3) (match_dup 1))
14099    (set (match_dup 4) (match_dup 2))]
14101   unsigned dest_hi = REGNO (operands[0]);
14102   unsigned dest_lo = dest_hi + 1;
14104   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14105   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14107   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14108   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14110   [(set_attr "type" "fpsimple,fp")
14111    (set_attr "length" "4,8")])
14113 (define_insn "unpack<mode>"
14114   [(set (match_operand:DI 0 "register_operand" "=d,d")
14115         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14116                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14117          UNSPEC_UNPACK_128BIT))]
14118   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14120   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14121     return ASM_COMMENT_START " xxpermdi to same register";
14123   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14124   return "xxpermdi %x0,%x1,%x1,%3";
14126   [(set_attr "type" "vecperm")])
14128 (define_insn "pack<mode>"
14129   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14130         (unspec:FMOVE128_VSX
14131          [(match_operand:DI 1 "register_operand" "d")
14132           (match_operand:DI 2 "register_operand" "d")]
14133          UNSPEC_PACK_128BIT))]
14134   "TARGET_VSX"
14135   "xxpermdi %x0,%x1,%x2,0"
14136   [(set_attr "type" "vecperm")])
14140 ;; ISA 2.08 IEEE 128-bit floating point support.
14142 (define_insn "add<mode>3"
14143   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14144         (plus:IEEE128
14145          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14146          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14147   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14148   "xsaddqp %0,%1,%2"
14149   [(set_attr "type" "vecfloat")
14150    (set_attr "size" "128")])
14152 (define_insn "sub<mode>3"
14153   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14154         (minus:IEEE128
14155          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14156          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14157   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14158   "xssubqp %0,%1,%2"
14159   [(set_attr "type" "vecfloat")
14160    (set_attr "size" "128")])
14162 (define_insn "mul<mode>3"
14163   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14164         (mult:IEEE128
14165          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14166          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14167   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14168   "xsmulqp %0,%1,%2"
14169   [(set_attr "type" "vecfloat")
14170    (set_attr "size" "128")])
14172 (define_insn "div<mode>3"
14173   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14174         (div:IEEE128
14175          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14176          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14177   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14178   "xsdivqp %0,%1,%2"
14179   [(set_attr "type" "vecdiv")
14180    (set_attr "size" "128")])
14182 (define_insn "sqrt<mode>2"
14183   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14184         (sqrt:IEEE128
14185          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14186   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14187    "xssqrtqp %0,%1"
14188   [(set_attr "type" "vecdiv")
14189    (set_attr "size" "128")])
14191 (define_expand "copysign<mode>3"
14192   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14193    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14194    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14195   "FLOAT128_IEEE_P (<MODE>mode)"
14197   if (TARGET_FLOAT128_HW)
14198     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14199                                          operands[2]));
14200   else
14201     {
14202       rtx tmp = gen_reg_rtx (<MODE>mode);
14203       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14204                                            operands[2], tmp));
14205     }
14206   DONE;
14209 (define_insn "copysign<mode>3_hard"
14210   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14211         (unspec:IEEE128
14212          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14213           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14214          UNSPEC_COPYSIGN))]
14215   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14216    "xscpsgnqp %0,%2,%1"
14217   [(set_attr "type" "vecmove")
14218    (set_attr "size" "128")])
14220 (define_insn "copysign<mode>3_soft"
14221   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14222         (unspec:IEEE128
14223          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14224           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14225           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14226          UNSPEC_COPYSIGN))]
14227   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14228    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14229   [(set_attr "type" "veccomplex")
14230    (set_attr "length" "8")])
14232 (define_insn "neg<mode>2_hw"
14233   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14234         (neg:IEEE128
14235          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14236   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14237   "xsnegqp %0,%1"
14238   [(set_attr "type" "vecmove")
14239    (set_attr "size" "128")])
14242 (define_insn "abs<mode>2_hw"
14243   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14244         (abs:IEEE128
14245          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14246   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14247   "xsabsqp %0,%1"
14248   [(set_attr "type" "vecmove")
14249    (set_attr "size" "128")])
14252 (define_insn "*nabs<mode>2_hw"
14253   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14254         (neg:IEEE128
14255          (abs:IEEE128
14256           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14257   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14258   "xsnabsqp %0,%1"
14259   [(set_attr "type" "vecmove")
14260    (set_attr "size" "128")])
14262 ;; Initially don't worry about doing fusion
14263 (define_insn "*fma<mode>4_hw"
14264   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14265         (fma:IEEE128
14266          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14267          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14268          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14269   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14270   "xsmaddqp %0,%1,%2"
14271   [(set_attr "type" "vecfloat")
14272    (set_attr "size" "128")])
14274 (define_insn "*fms<mode>4_hw"
14275   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14276         (fma:IEEE128
14277          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14278          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14279          (neg:IEEE128
14280           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14281   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14282   "xsmsubqp %0,%1,%2"
14283   [(set_attr "type" "vecfloat")
14284    (set_attr "size" "128")])
14286 (define_insn "*nfma<mode>4_hw"
14287   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14288         (neg:IEEE128
14289          (fma:IEEE128
14290           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14291           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14292           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14293   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14294   "xsnmaddqp %0,%1,%2"
14295   [(set_attr "type" "vecfloat")
14296    (set_attr "size" "128")])
14298 (define_insn "*nfms<mode>4_hw"
14299   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14300         (neg:IEEE128
14301          (fma:IEEE128
14302           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14303           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14304           (neg:IEEE128
14305            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14306   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14307   "xsnmsubqp %0,%1,%2"
14308   [(set_attr "type" "vecfloat")
14309    (set_attr "size" "128")])
14311 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14312   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14313         (float_extend:IEEE128
14314          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14315   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14316   "xscvdpqp %0,%1"
14317   [(set_attr "type" "vecfloat")
14318    (set_attr "size" "128")])
14320 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14321 ;; point is a simple copy.
14322 (define_insn_and_split "extendkftf2"
14323   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14324         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14325   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14326   "@
14327    #
14328    xxlor %x0,%x1,%x1"
14329   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14330   [(const_int 0)]
14332   emit_note (NOTE_INSN_DELETED);
14333   DONE;
14335   [(set_attr "type" "*,veclogical")
14336    (set_attr "length" "0,4")])
14338 (define_insn_and_split "trunctfkf2"
14339   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14340         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14341   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14342   "@
14343    #
14344    xxlor %x0,%x1,%x1"
14345   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14346   [(const_int 0)]
14348   emit_note (NOTE_INSN_DELETED);
14349   DONE;
14351   [(set_attr "type" "*,veclogical")
14352    (set_attr "length" "0,4")])
14354 (define_insn "trunc<mode>df2_hw"
14355   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14356         (float_truncate:DF
14357          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14358   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14359   "xscvqpdp %0,%1"
14360   [(set_attr "type" "vecfloat")
14361    (set_attr "size" "128")])
14363 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14364 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14365 ;; conversion
14366 (define_insn_and_split "trunc<mode>sf2_hw"
14367   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14368         (float_truncate:SF
14369          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14370    (clobber (match_scratch:DF 2 "=v"))]
14371   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14372   "#"
14373   "&& 1"
14374   [(set (match_dup 2)
14375         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14376    (set (match_dup 0)
14377         (float_truncate:SF (match_dup 2)))]
14379   if (GET_CODE (operands[2]) == SCRATCH)
14380     operands[2] = gen_reg_rtx (DFmode);
14382   [(set_attr "type" "vecfloat")
14383    (set_attr "length" "8")])
14385 ;; Conversion between IEEE 128-bit and integer types
14386 (define_insn "fix_<mode>di2_hw"
14387   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14388         (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14389   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14390   "xscvqpsdz %0,%1"
14391   [(set_attr "type" "vecfloat")
14392    (set_attr "size" "128")])
14394 (define_insn "fixuns_<mode>di2_hw"
14395   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14396         (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14397   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14398   "xscvqpudz %0,%1"
14399   [(set_attr "type" "vecfloat")
14400    (set_attr "size" "128")])
14402 (define_insn "fix_<mode>si2_hw"
14403   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14404         (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14405   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14406   "xscvqpswz %0,%1"
14407   [(set_attr "type" "vecfloat")
14408    (set_attr "size" "128")])
14410 (define_insn "fixuns_<mode>si2_hw"
14411   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14412         (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14413   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14414   "xscvqpuwz %0,%1"
14415   [(set_attr "type" "vecfloat")
14416    (set_attr "size" "128")])
14418 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14419 ;; floating point value to 32-bit integer to GPR in order to save it.
14420 (define_insn_and_split "*fix<uns>_<mode>_mem"
14421   [(set (match_operand:SI 0 "memory_operand" "=Z")
14422         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14423    (clobber (match_scratch:SI 2 "=v"))]
14424   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14425   "#"
14426   "&& reload_completed"
14427   [(set (match_dup 2)
14428         (any_fix:SI (match_dup 1)))
14429    (set (match_dup 0)
14430         (match_dup 2))])
14432 (define_insn "float_<mode>di2_hw"
14433   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14434         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14435   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14436   "xscvsdqp %0,%1"
14437   [(set_attr "type" "vecfloat")
14438    (set_attr "size" "128")])
14440 (define_insn_and_split "float_<mode>si2_hw"
14441   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14442         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14443    (clobber (match_scratch:DI 2 "=v"))]
14444   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14445   "#"
14446   "&& 1"
14447   [(set (match_dup 2)
14448         (sign_extend:DI (match_dup 1)))
14449    (set (match_dup 0)
14450         (float:IEEE128 (match_dup 2)))]
14452   if (GET_CODE (operands[2]) == SCRATCH)
14453     operands[2] = gen_reg_rtx (DImode);
14456 (define_insn "floatuns_<mode>di2_hw"
14457   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14458         (unsigned_float:IEEE128
14459          (match_operand:DI 1 "altivec_register_operand" "v")))]
14460   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14461   "xscvudqp %0,%1"
14462   [(set_attr "type" "vecfloat")
14463    (set_attr "size" "128")])
14465 (define_insn_and_split "floatuns_<mode>si2_hw"
14466   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14467         (unsigned_float:IEEE128
14468          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14469    (clobber (match_scratch:DI 2 "=v"))]
14470   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14471   "#"
14472   "&& 1"
14473   [(set (match_dup 2)
14474         (zero_extend:DI (match_dup 1)))
14475    (set (match_dup 0)
14476         (float:IEEE128 (match_dup 2)))]
14478   if (GET_CODE (operands[2]) == SCRATCH)
14479     operands[2] = gen_reg_rtx (DImode);
14482 ;; IEEE 128-bit instructions with round to odd semantics
14483 (define_insn "*trunc<mode>df2_odd"
14484   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14485         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14486                    UNSPEC_ROUND_TO_ODD))]
14487   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14488   "xscvqpdpo %0,%1"
14489   [(set_attr "type" "vecfloat")
14490    (set_attr "size" "128")])
14492 ;; IEEE 128-bit comparisons
14493 (define_insn "*cmp<mode>_hw"
14494   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14495         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14496                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14497   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14498    "xscmpuqp %0,%1,%2"
14499   [(set_attr "type" "veccmp")
14500    (set_attr "size" "128")])
14504 (include "sync.md")
14505 (include "vector.md")
14506 (include "vsx.md")
14507 (include "altivec.md")
14508 (include "spe.md")
14509 (include "dfp.md")
14510 (include "paired.md")
14511 (include "crypto.md")
14512 (include "htm.md")