re PR target/79004 (ICE in gcc.dg/torture/fp-int-convert-float128-ieee.c with -mcpu...
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
bloba094b92a96e81a27ce028f347bdbd1a4c7fc3704
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_IEEE128_MOVE
150    UNSPEC_IEEE128_CONVERT
151    UNSPEC_SIGNBIT
152    UNSPEC_DOLOOP
153    UNSPEC_SF_FROM_SI
154    UNSPEC_SI_FROM_SF
155   ])
158 ;; UNSPEC_VOLATILE usage
161 (define_c_enum "unspecv"
162   [UNSPECV_BLOCK
163    UNSPECV_LL                   ; load-locked
164    UNSPECV_SC                   ; store-conditional
165    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
166    UNSPECV_EH_RR                ; eh_reg_restore
167    UNSPECV_ISYNC                ; isync instruction
168    UNSPECV_MFTB                 ; move from time base
169    UNSPECV_NLGR                 ; non-local goto receiver
170    UNSPECV_MFFS                 ; Move from FPSCR
171    UNSPECV_MTFSF                ; Move to FPSCR Fields
172    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
173   ])
176 ;; Define an insn type attribute.  This is used in function unit delay
177 ;; computations.
178 (define_attr "type"
179   "integer,two,three,
180    add,logical,shift,insert,
181    mul,halfmul,div,
182    exts,cntlz,popcnt,isel,
183    load,store,fpload,fpstore,vecload,vecstore,
184    cmp,
185    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
186    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
187    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
188    brinc,
189    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
190    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
191    veclogical,veccmpfx,vecexts,vecmove,
192    htm,htmsimple,dfp"
193   (const_string "integer"))
195 ;; What data size does this instruction work on?
196 ;; This is used for insert, mul and others as necessary.
197 (define_attr "size" "8,16,32,64,128" (const_string "32"))
199 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
200 ;; This is used for add, logical, shift, exts, mul.
201 (define_attr "dot" "no,yes" (const_string "no"))
203 ;; Does this instruction sign-extend its result?
204 ;; This is used for load insns.
205 (define_attr "sign_extend" "no,yes" (const_string "no"))
207 ;; Does this instruction use indexed (that is, reg+reg) addressing?
208 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
209 ;; it is automatically set based on that.  If a load or store instruction
210 ;; has fewer than two operands it needs to set this attribute manually
211 ;; or the compiler will crash.
212 (define_attr "indexed" "no,yes"
213   (if_then_else (ior (match_operand 0 "indexed_address_mem")
214                      (match_operand 1 "indexed_address_mem"))
215                 (const_string "yes")
216                 (const_string "no")))
218 ;; Does this instruction use update addressing?
219 ;; This is used for load and store insns.  See the comments for "indexed".
220 (define_attr "update" "no,yes"
221   (if_then_else (ior (match_operand 0 "update_address_mem")
222                      (match_operand 1 "update_address_mem"))
223                 (const_string "yes")
224                 (const_string "no")))
226 ;; Is this instruction using operands[2] as shift amount, and can that be a
227 ;; register?
228 ;; This is used for shift insns.
229 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
231 ;; Is this instruction using a shift amount from a register?
232 ;; This is used for shift insns.
233 (define_attr "var_shift" "no,yes"
234   (if_then_else (and (eq_attr "type" "shift")
235                      (eq_attr "maybe_var_shift" "yes"))
236                 (if_then_else (match_operand 2 "gpc_reg_operand")
237                               (const_string "yes")
238                               (const_string "no"))
239                 (const_string "no")))
241 ;; Is copying of this instruction disallowed?
242 (define_attr "cannot_copy" "no,yes" (const_string "no"))
244 ;; Define floating point instruction sub-types for use with Xfpu.md
245 (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"))
247 ;; Length (in bytes).
248 ; '(pc)' in the following doesn't include the instruction itself; it is
249 ; calculated as if the instruction had zero size.
250 (define_attr "length" ""
251   (if_then_else (eq_attr "type" "branch")
252                 (if_then_else (and (ge (minus (match_dup 0) (pc))
253                                        (const_int -32768))
254                                    (lt (minus (match_dup 0) (pc))
255                                        (const_int 32764)))
256                               (const_int 4)
257                               (const_int 8))
258                 (const_int 4)))
260 ;; Processor type -- this attribute must exactly match the processor_type
261 ;; enumeration in rs6000-opts.h.
262 (define_attr "cpu"
263   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
264    ppc750,ppc7400,ppc7450,
265    ppc403,ppc405,ppc440,ppc476,
266    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
267    power4,power5,power6,power7,power8,power9,
268    rs64a,mpccore,cell,ppca2,titan"
269   (const (symbol_ref "rs6000_cpu_attr")))
272 ;; If this instruction is microcoded on the CELL processor
273 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
274 (define_attr "cell_micro" "not,conditional,always"
275   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
276                           (eq_attr "dot" "yes"))
277                      (and (eq_attr "type" "load")
278                           (eq_attr "sign_extend" "yes"))
279                      (and (eq_attr "type" "shift")
280                           (eq_attr "var_shift" "yes")))
281                 (const_string "always")
282                 (const_string "not")))
284 (automata_option "ndfa")
286 (include "rs64.md")
287 (include "mpc.md")
288 (include "40x.md")
289 (include "440.md")
290 (include "476.md")
291 (include "601.md")
292 (include "603.md")
293 (include "6xx.md")
294 (include "7xx.md")
295 (include "7450.md")
296 (include "8540.md")
297 (include "e300c2c3.md")
298 (include "e500mc.md")
299 (include "e500mc64.md")
300 (include "e5500.md")
301 (include "e6500.md")
302 (include "power4.md")
303 (include "power5.md")
304 (include "power6.md")
305 (include "power7.md")
306 (include "power8.md")
307 (include "power9.md")
308 (include "cell.md")
309 (include "xfpu.md")
310 (include "a2.md")
311 (include "titan.md")
313 (include "predicates.md")
314 (include "constraints.md")
316 (include "darwin.md")
319 ;; Mode iterators
321 ; This mode iterator allows :GPR to be used to indicate the allowable size
322 ; of whole values in GPRs.
323 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
325 ; Any supported integer mode.
326 (define_mode_iterator INT [QI HI SI DI TI PTI])
328 ; Any supported integer mode that fits in one register.
329 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
331 ; Integer modes supported in VSX registers with ISA 3.0 instructions
332 (define_mode_iterator INT_ISA3 [QI HI SI DI])
334 ; Everything we can extend QImode to.
335 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend HImode to.
338 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
340 ; Everything we can extend SImode to.
341 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
343 ; QImode or HImode for small integer moves and small atomic ops
344 (define_mode_iterator QHI [QI HI])
346 ; QImode, HImode, SImode for fused ops only for GPR loads
347 (define_mode_iterator QHSI [QI HI SI])
349 ; HImode or SImode for sign extended fusion ops
350 (define_mode_iterator HSI [HI SI])
352 ; SImode or DImode, even if DImode doesn't fit in GPRs.
353 (define_mode_iterator SDI [SI DI])
355 ; Types that can be fused with an ADDIS instruction to load or store a GPR
356 ; register that has reg+offset addressing.
357 (define_mode_iterator GPR_FUSION [QI
358                                   HI
359                                   SI
360                                   (DI   "TARGET_POWERPC64")
361                                   SF
362                                   (DF   "TARGET_POWERPC64")])
364 ; Types that can be fused with an ADDIS instruction to load or store a FPR
365 ; register that has reg+offset addressing.
366 (define_mode_iterator FPR_FUSION [DI SF DF])
368 ; The size of a pointer.  Also, the size of the value that a record-condition
369 ; (one with a '.') will compare; and the size used for arithmetic carries.
370 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
372 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
373 ; PTImode is GPR only)
374 (define_mode_iterator TI2 [TI PTI])
376 ; Any hardware-supported floating-point mode
377 (define_mode_iterator FP [
378   (SF "TARGET_HARD_FLOAT 
379    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
380   (DF "TARGET_HARD_FLOAT 
381    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
382   (TF "TARGET_HARD_FLOAT
383    && (TARGET_FPRS || TARGET_E500_DOUBLE)
384    && TARGET_LONG_DOUBLE_128")
385   (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
386   (KF "TARGET_FLOAT128_TYPE")
387   (DD "TARGET_DFP")
388   (TD "TARGET_DFP")])
390 ; Any fma capable floating-point mode.
391 (define_mode_iterator FMA_F [
392   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
393   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
394        || VECTOR_UNIT_VSX_P (DFmode)")
395   (V2SF "TARGET_PAIRED_FLOAT")
396   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
397   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
398   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
399   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
400   ])
402 ; Floating point move iterators to combine binary and decimal moves
403 (define_mode_iterator FMOVE32 [SF SD])
404 (define_mode_iterator FMOVE64 [DF DD])
405 (define_mode_iterator FMOVE64X [DI DF DD])
406 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
407                                 (IF "FLOAT128_IBM_P (IFmode)")
408                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
410 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
411                                     (IF "FLOAT128_2REG_P (IFmode)")
412                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
414 ; Iterators for 128 bit types for direct move
415 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
416                                     (V16QI "")
417                                     (V8HI  "")
418                                     (V4SI  "")
419                                     (V4SF  "")
420                                     (V2DI  "")
421                                     (V2DF  "")
422                                     (V1TI  "")
423                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
424                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
426 ; Iterator for 128-bit VSX types for pack/unpack
427 (define_mode_iterator FMOVE128_VSX [V1TI KF])
429 ; Whether a floating point move is ok, don't allow SD without hardware FP
430 (define_mode_attr fmove_ok [(SF "")
431                             (DF "")
432                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
433                             (DD "")])
435 ; Convert REAL_VALUE to the appropriate bits
436 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
437                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
438                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
439                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
441 ; Whether 0.0 has an all-zero bit pattern
442 (define_mode_attr zero_fp [(SF "j")
443                            (DF "j")
444                            (TF "j")
445                            (IF "j")
446                            (KF "j")
447                            (SD "wn")
448                            (DD "wn")
449                            (TD "wn")])
451 ; Definitions for load to 32-bit fpr register
452 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
453 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
454 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
455 (define_mode_attr f32_lm2 [(SF "wY")              (SD "wn")])
456 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
457 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
458 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
460 ; Definitions for store from 32-bit fpr register
461 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
462 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
463 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
464 (define_mode_attr f32_sm2 [(SF "wY")               (SD "wn")])
465 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
466 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
467 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwx %x1,%y0")])
469 ; Definitions for 32-bit fpr direct move
470 ; At present, the decimal modes are not allowed in the traditional altivec
471 ; registers, so restrict the constraints to just the traditional FPRs.
472 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
474 ; Definitions for 32-bit VSX
475 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
477 ; Definitions for 32-bit use of altivec registers
478 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
480 ; Definitions for 64-bit VSX
481 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
483 ; Definitions for 64-bit direct move
484 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
486 ; Definitions for 64-bit use of altivec registers
487 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
489 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
490 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
492 ; These modes do not fit in integer registers in 32-bit mode.
493 ; but on e500v2, the gpr are 64 bit registers
494 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
496 ; Iterator for reciprocal estimate instructions
497 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
499 ; Iterator for just SF/DF
500 (define_mode_iterator SFDF [SF DF])
502 ; Like SFDF, but a different name to match conditional move where the
503 ; comparison operands may be a different mode than the input operands.
504 (define_mode_iterator SFDF2 [SF DF])
506 ; Iterator for 128-bit floating point that uses the IBM double-double format
507 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
508                               (TF "FLOAT128_IBM_P (TFmode)")])
510 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
511 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
512                                (TF "FLOAT128_IEEE_P (TFmode)")])
514 ; Iterator for 128-bit floating point
515 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
516                                 (IF "TARGET_FLOAT128_TYPE")
517                                 (TF "TARGET_LONG_DOUBLE_128")])
519 ; Iterator for signbit on 64-bit machines with direct move
520 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
521                                (TF "FLOAT128_VECTOR_P (TFmode)")])
523 ; Iterator for ISA 3.0 supported floating point types
524 (define_mode_iterator FP_ISA3 [SF DF])
526 ; SF/DF suffix for traditional floating instructions
527 (define_mode_attr Ftrad         [(SF "s") (DF "")])
529 ; SF/DF suffix for VSX instructions
530 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
532 ; SF/DF constraint for arithmetic on traditional floating point registers
533 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
535 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
536 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
537 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
538 ; format.
539 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
541 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
542 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
543 ; instructions added in ISA 2.07 (power8)
544 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
546 ; SF/DF constraint for arithmetic on altivec registers
547 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
549 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
550 (define_mode_attr Fs            [(SF "s")  (DF "d")])
552 ; FRE/FRES support
553 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
554 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
556 ; Conditional returns.
557 (define_code_iterator any_return [return simple_return])
558 (define_code_attr return_pred [(return "direct_return ()")
559                                (simple_return "1")])
560 (define_code_attr return_str [(return "") (simple_return "simple_")])
562 ; Logical operators.
563 (define_code_iterator iorxor            [ior xor])
564 (define_code_iterator and_ior_xor       [and ior xor])
566 ; Signed/unsigned variants of ops.
567 (define_code_iterator any_extend        [sign_extend zero_extend])
568 (define_code_iterator any_fix           [fix unsigned_fix])
569 (define_code_iterator any_float         [float unsigned_float])
571 (define_code_attr u  [(sign_extend      "")
572                       (zero_extend      "u")])
574 (define_code_attr su [(sign_extend      "s")
575                       (zero_extend      "u")
576                       (fix              "s")
577                       (unsigned_fix     "s")
578                       (float            "s")
579                       (unsigned_float   "u")])
581 (define_code_attr az [(sign_extend      "a")
582                       (zero_extend      "z")
583                       (fix              "a")
584                       (unsigned_fix     "z")
585                       (float            "a")
586                       (unsigned_float   "z")])
588 (define_code_attr uns [(fix             "")
589                        (unsigned_fix    "uns")
590                        (float           "")
591                        (unsigned_float  "uns")])
593 ; Various instructions that come in SI and DI forms.
594 ; A generic w/d attribute, for things like cmpw/cmpd.
595 (define_mode_attr wd [(QI    "b")
596                       (HI    "h")
597                       (SI    "w")
598                       (DI    "d")
599                       (V16QI "b")
600                       (V8HI  "h")
601                       (V4SI  "w")
602                       (V2DI  "d")
603                       (V1TI  "q")
604                       (TI    "q")])
606 ;; How many bits in this mode?
607 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
609 ; DImode bits
610 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
612 ;; ISEL/ISEL64 target selection
613 (define_mode_attr sel [(SI "") (DI "64")])
615 ;; Bitmask for shift instructions
616 (define_mode_attr hH [(SI "h") (DI "H")])
618 ;; A mode twice the size of the given mode
619 (define_mode_attr dmode [(SI "di") (DI "ti")])
620 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
622 ;; Suffix for reload patterns
623 (define_mode_attr ptrsize [(SI "32bit")
624                            (DI "64bit")])
626 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
627                             (DI "TARGET_64BIT")])
629 (define_mode_attr mptrsize [(SI "si")
630                             (DI "di")])
632 (define_mode_attr ptrload [(SI "lwz")
633                            (DI "ld")])
635 (define_mode_attr ptrm [(SI "m")
636                         (DI "Y")])
638 (define_mode_attr rreg [(SF   "f")
639                         (DF   "ws")
640                         (TF   "f")
641                         (TD   "f")
642                         (V4SF "wf")
643                         (V2DF "wd")])
645 (define_mode_attr rreg2 [(SF   "f")
646                          (DF   "d")])
648 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
649                                  (DF "TARGET_FCFID")])
651 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
652                                 (DF "TARGET_E500_DOUBLE")])
654 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
655                                 (DF "TARGET_DOUBLE_FLOAT")])
657 ;; Mode iterator for logical operations on 128-bit types
658 (define_mode_iterator BOOL_128          [TI
659                                          PTI
660                                          (V16QI "TARGET_ALTIVEC")
661                                          (V8HI  "TARGET_ALTIVEC")
662                                          (V4SI  "TARGET_ALTIVEC")
663                                          (V4SF  "TARGET_ALTIVEC")
664                                          (V2DI  "TARGET_ALTIVEC")
665                                          (V2DF  "TARGET_ALTIVEC")
666                                          (V1TI  "TARGET_ALTIVEC")])
668 ;; For the GPRs we use 3 constraints for register outputs, two that are the
669 ;; same as the output register, and a third where the output register is an
670 ;; early clobber, so we don't have to deal with register overlaps.  For the
671 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
672 ;; either.
674 ;; Mode attribute for boolean operation register constraints for output
675 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
676                                          (PTI   "&r,r,r")
677                                          (V16QI "wa,v,&?r,?r,?r")
678                                          (V8HI  "wa,v,&?r,?r,?r")
679                                          (V4SI  "wa,v,&?r,?r,?r")
680                                          (V4SF  "wa,v,&?r,?r,?r")
681                                          (V2DI  "wa,v,&?r,?r,?r")
682                                          (V2DF  "wa,v,&?r,?r,?r")
683                                          (V1TI  "wa,v,&?r,?r,?r")])
685 ;; Mode attribute for boolean operation register constraints for operand1
686 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
687                                          (PTI   "r,0,r")
688                                          (V16QI "wa,v,r,0,r")
689                                          (V8HI  "wa,v,r,0,r")
690                                          (V4SI  "wa,v,r,0,r")
691                                          (V4SF  "wa,v,r,0,r")
692                                          (V2DI  "wa,v,r,0,r")
693                                          (V2DF  "wa,v,r,0,r")
694                                          (V1TI  "wa,v,r,0,r")])
696 ;; Mode attribute for boolean operation register constraints for operand2
697 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
698                                          (PTI   "r,r,0")
699                                          (V16QI "wa,v,r,r,0")
700                                          (V8HI  "wa,v,r,r,0")
701                                          (V4SI  "wa,v,r,r,0")
702                                          (V4SF  "wa,v,r,r,0")
703                                          (V2DI  "wa,v,r,r,0")
704                                          (V2DF  "wa,v,r,r,0")
705                                          (V1TI  "wa,v,r,r,0")])
707 ;; Mode attribute for boolean operation register constraints for operand1
708 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
709 ;; is used for operand1 or operand2
710 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
711                                          (PTI   "r,0,0")
712                                          (V16QI "wa,v,r,0,0")
713                                          (V8HI  "wa,v,r,0,0")
714                                          (V4SI  "wa,v,r,0,0")
715                                          (V4SF  "wa,v,r,0,0")
716                                          (V2DI  "wa,v,r,0,0")
717                                          (V2DF  "wa,v,r,0,0")
718                                          (V1TI  "wa,v,r,0,0")])
720 ;; Reload iterator for creating the function to allocate a base register to
721 ;; supplement addressing modes.
722 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
723                               SF SD SI DF DD DI TI PTI KF IF TF])
725 ;; Iterate over smin, smax
726 (define_code_iterator fp_minmax [smin smax])
728 (define_code_attr     minmax    [(smin "min")
729                                  (smax "max")])
731 (define_code_attr     SMINMAX   [(smin "SMIN")
732                                  (smax "SMAX")])
735 ;; Start with fixed-point load and store insns.  Here we put only the more
736 ;; complex forms.  Basic data transfer is done later.
738 (define_insn "zero_extendqi<mode>2"
739   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
740         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
741   ""
742   "@
743    lbz%U1%X1 %0,%1
744    rlwinm %0,%1,0,0xff
745    lxsibzx %x0,%y1
746    vextractub %0,%1,7"
747   [(set_attr "type" "load,shift,fpload,vecperm")])
749 (define_insn_and_split "*zero_extendqi<mode>2_dot"
750   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
751         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
752                     (const_int 0)))
753    (clobber (match_scratch:EXTQI 0 "=r,r"))]
754   "rs6000_gen_cell_microcode"
755   "@
756    andi. %0,%1,0xff
757    #"
758   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
759   [(set (match_dup 0)
760         (zero_extend:EXTQI (match_dup 1)))
761    (set (match_dup 2)
762         (compare:CC (match_dup 0)
763                     (const_int 0)))]
764   ""
765   [(set_attr "type" "logical")
766    (set_attr "dot" "yes")
767    (set_attr "length" "4,8")])
769 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
770   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
771         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
772                     (const_int 0)))
773    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
774         (zero_extend:EXTQI (match_dup 1)))]
775   "rs6000_gen_cell_microcode"
776   "@
777    andi. %0,%1,0xff
778    #"
779   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
780   [(set (match_dup 0)
781         (zero_extend:EXTQI (match_dup 1)))
782    (set (match_dup 2)
783         (compare:CC (match_dup 0)
784                     (const_int 0)))]
785   ""
786   [(set_attr "type" "logical")
787    (set_attr "dot" "yes")
788    (set_attr "length" "4,8")])
791 (define_insn "zero_extendhi<mode>2"
792   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
793         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
794   ""
795   "@
796    lhz%U1%X1 %0,%1
797    rlwinm %0,%1,0,0xffff
798    lxsihzx %x0,%y1
799    vextractuh %0,%1,6"
800   [(set_attr "type" "load,shift,fpload,vecperm")])
802 (define_insn_and_split "*zero_extendhi<mode>2_dot"
803   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
804         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
805                     (const_int 0)))
806    (clobber (match_scratch:EXTHI 0 "=r,r"))]
807   "rs6000_gen_cell_microcode"
808   "@
809    andi. %0,%1,0xffff
810    #"
811   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
812   [(set (match_dup 0)
813         (zero_extend:EXTHI (match_dup 1)))
814    (set (match_dup 2)
815         (compare:CC (match_dup 0)
816                     (const_int 0)))]
817   ""
818   [(set_attr "type" "logical")
819    (set_attr "dot" "yes")
820    (set_attr "length" "4,8")])
822 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
823   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
824         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
825                     (const_int 0)))
826    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
827         (zero_extend:EXTHI (match_dup 1)))]
828   "rs6000_gen_cell_microcode"
829   "@
830    andi. %0,%1,0xffff
831    #"
832   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
833   [(set (match_dup 0)
834         (zero_extend:EXTHI (match_dup 1)))
835    (set (match_dup 2)
836         (compare:CC (match_dup 0)
837                     (const_int 0)))]
838   ""
839   [(set_attr "type" "logical")
840    (set_attr "dot" "yes")
841    (set_attr "length" "4,8")])
844 (define_insn "zero_extendsi<mode>2"
845   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
846         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
847   ""
848   "@
849    lwz%U1%X1 %0,%1
850    rldicl %0,%1,0,32
851    lfiwzx %0,%y1
852    lxsiwzx %x0,%y1
853    mtvsrwz %x0,%1
854    mfvsrwz %0,%x1
855    xxextractuw %x0,%x1,4"
856   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
858 (define_insn_and_split "*zero_extendsi<mode>2_dot"
859   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
860         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
861                     (const_int 0)))
862    (clobber (match_scratch:EXTSI 0 "=r,r"))]
863   "rs6000_gen_cell_microcode"
864   "@
865    rldicl. %0,%1,0,32
866    #"
867   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
868   [(set (match_dup 0)
869         (zero_extend:DI (match_dup 1)))
870    (set (match_dup 2)
871         (compare:CC (match_dup 0)
872                     (const_int 0)))]
873   ""
874   [(set_attr "type" "shift")
875    (set_attr "dot" "yes")
876    (set_attr "length" "4,8")])
878 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
879   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
881                     (const_int 0)))
882    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
883         (zero_extend:EXTSI (match_dup 1)))]
884   "rs6000_gen_cell_microcode"
885   "@
886    rldicl. %0,%1,0,32
887    #"
888   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
889   [(set (match_dup 0)
890         (zero_extend:EXTSI (match_dup 1)))
891    (set (match_dup 2)
892         (compare:CC (match_dup 0)
893                     (const_int 0)))]
894   ""
895   [(set_attr "type" "shift")
896    (set_attr "dot" "yes")
897    (set_attr "length" "4,8")])
900 (define_insn "extendqi<mode>2"
901   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
902         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
903   ""
904   "@
905    extsb %0,%1
906    vextsb2d %0,%1"
907   [(set_attr "type" "exts,vecperm")])
909 (define_insn_and_split "*extendqi<mode>2_dot"
910   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
911         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
912                     (const_int 0)))
913    (clobber (match_scratch:EXTQI 0 "=r,r"))]
914   "rs6000_gen_cell_microcode"
915   "@
916    extsb. %0,%1
917    #"
918   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
919   [(set (match_dup 0)
920         (sign_extend:EXTQI (match_dup 1)))
921    (set (match_dup 2)
922         (compare:CC (match_dup 0)
923                     (const_int 0)))]
924   ""
925   [(set_attr "type" "exts")
926    (set_attr "dot" "yes")
927    (set_attr "length" "4,8")])
929 (define_insn_and_split "*extendqi<mode>2_dot2"
930   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
931         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
932                     (const_int 0)))
933    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
934         (sign_extend:EXTQI (match_dup 1)))]
935   "rs6000_gen_cell_microcode"
936   "@
937    extsb. %0,%1
938    #"
939   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
940   [(set (match_dup 0)
941         (sign_extend:EXTQI (match_dup 1)))
942    (set (match_dup 2)
943         (compare:CC (match_dup 0)
944                     (const_int 0)))]
945   ""
946   [(set_attr "type" "exts")
947    (set_attr "dot" "yes")
948    (set_attr "length" "4,8")])
951 (define_expand "extendhi<mode>2"
952   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
953         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
954   ""
955   "")
957 (define_insn "*extendhi<mode>2"
958   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
959         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
960   "rs6000_gen_cell_microcode"
961   "@
962    lha%U1%X1 %0,%1
963    extsh %0,%1
964    #
965    vextsh2d %0,%1"
966   [(set_attr "type" "load,exts,fpload,vecperm")
967    (set_attr "sign_extend" "yes")
968    (set_attr "length" "4,4,8,4")])
970 (define_split
971   [(set (match_operand:EXTHI 0 "altivec_register_operand")
972         (sign_extend:EXTHI
973          (match_operand:HI 1 "indexed_or_indirect_operand")))]
974   "TARGET_P9_VECTOR && reload_completed"
975   [(set (match_dup 2)
976         (match_dup 1))
977    (set (match_dup 0)
978         (sign_extend:EXTHI (match_dup 2)))]
980   operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
983 (define_insn "*extendhi<mode>2_noload"
984   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
985         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
986   "!rs6000_gen_cell_microcode"
987   "extsh %0,%1"
988   [(set_attr "type" "exts")])
990 (define_insn_and_split "*extendhi<mode>2_dot"
991   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
992         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
993                     (const_int 0)))
994    (clobber (match_scratch:EXTHI 0 "=r,r"))]
995   "rs6000_gen_cell_microcode"
996   "@
997    extsh. %0,%1
998    #"
999   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1000   [(set (match_dup 0)
1001         (sign_extend:EXTHI (match_dup 1)))
1002    (set (match_dup 2)
1003         (compare:CC (match_dup 0)
1004                     (const_int 0)))]
1005   ""
1006   [(set_attr "type" "exts")
1007    (set_attr "dot" "yes")
1008    (set_attr "length" "4,8")])
1010 (define_insn_and_split "*extendhi<mode>2_dot2"
1011   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1012         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1013                     (const_int 0)))
1014    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1015         (sign_extend:EXTHI (match_dup 1)))]
1016   "rs6000_gen_cell_microcode"
1017   "@
1018    extsh. %0,%1
1019    #"
1020   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1021   [(set (match_dup 0)
1022         (sign_extend:EXTHI (match_dup 1)))
1023    (set (match_dup 2)
1024         (compare:CC (match_dup 0)
1025                     (const_int 0)))]
1026   ""
1027   [(set_attr "type" "exts")
1028    (set_attr "dot" "yes")
1029    (set_attr "length" "4,8")])
1032 (define_insn "extendsi<mode>2"
1033   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1034         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1035   ""
1036   "@
1037    lwa%U1%X1 %0,%1
1038    extsw %0,%1
1039    lfiwax %0,%y1
1040    lxsiwax %x0,%y1
1041    mtvsrwa %x0,%1
1042    vextsw2d %0,%1"
1043   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1044    (set_attr "sign_extend" "yes")])
1046 (define_insn_and_split "*extendsi<mode>2_dot"
1047   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1048         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1049                     (const_int 0)))
1050    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1051   "rs6000_gen_cell_microcode"
1052   "@
1053    extsw. %0,%1
1054    #"
1055   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1056   [(set (match_dup 0)
1057         (sign_extend:EXTSI (match_dup 1)))
1058    (set (match_dup 2)
1059         (compare:CC (match_dup 0)
1060                     (const_int 0)))]
1061   ""
1062   [(set_attr "type" "exts")
1063    (set_attr "dot" "yes")
1064    (set_attr "length" "4,8")])
1066 (define_insn_and_split "*extendsi<mode>2_dot2"
1067   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1068         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1069                     (const_int 0)))
1070    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1071         (sign_extend:EXTSI (match_dup 1)))]
1072   "rs6000_gen_cell_microcode"
1073   "@
1074    extsw. %0,%1
1075    #"
1076   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1077   [(set (match_dup 0)
1078         (sign_extend:EXTSI (match_dup 1)))
1079    (set (match_dup 2)
1080         (compare:CC (match_dup 0)
1081                     (const_int 0)))]
1082   ""
1083   [(set_attr "type" "exts")
1084    (set_attr "dot" "yes")
1085    (set_attr "length" "4,8")])
1087 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1089 (define_insn "*macchwc"
1090   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1091         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1092                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1093                                        (const_int 16))
1094                                       (sign_extend:SI
1095                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1096                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1097                     (const_int 0)))
1098    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1099         (plus:SI (mult:SI (ashiftrt:SI
1100                            (match_dup 2)
1101                            (const_int 16))
1102                           (sign_extend:SI
1103                            (match_dup 1)))
1104                  (match_dup 4)))]
1105   "TARGET_MULHW"
1106   "macchw. %0,%1,%2"
1107   [(set_attr "type" "halfmul")])
1109 (define_insn "*macchw"
1110   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1111         (plus:SI (mult:SI (ashiftrt:SI
1112                            (match_operand:SI 2 "gpc_reg_operand" "r")
1113                            (const_int 16))
1114                           (sign_extend:SI
1115                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1116                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1117   "TARGET_MULHW"
1118   "macchw %0,%1,%2"
1119   [(set_attr "type" "halfmul")])
1121 (define_insn "*macchwuc"
1122   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1123         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1124                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1125                                        (const_int 16))
1126                                       (zero_extend:SI
1127                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1128                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1129                     (const_int 0)))
1130    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131         (plus:SI (mult:SI (lshiftrt:SI
1132                            (match_dup 2)
1133                            (const_int 16))
1134                           (zero_extend:SI
1135                            (match_dup 1)))
1136                  (match_dup 4)))]
1137   "TARGET_MULHW"
1138   "macchwu. %0,%1,%2"
1139   [(set_attr "type" "halfmul")])
1141 (define_insn "*macchwu"
1142   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1143         (plus:SI (mult:SI (lshiftrt:SI
1144                            (match_operand:SI 2 "gpc_reg_operand" "r")
1145                            (const_int 16))
1146                           (zero_extend:SI
1147                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1148                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1149   "TARGET_MULHW"
1150   "macchwu %0,%1,%2"
1151   [(set_attr "type" "halfmul")])
1153 (define_insn "*machhwc"
1154   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1155         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1156                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1157                                        (const_int 16))
1158                                       (ashiftrt:SI
1159                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1160                                        (const_int 16)))
1161                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1162                     (const_int 0)))
1163    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164         (plus:SI (mult:SI (ashiftrt:SI
1165                            (match_dup 1)
1166                            (const_int 16))
1167                           (ashiftrt:SI
1168                            (match_dup 2)
1169                            (const_int 16)))
1170                  (match_dup 4)))]
1171   "TARGET_MULHW"
1172   "machhw. %0,%1,%2"
1173   [(set_attr "type" "halfmul")])
1175 (define_insn "*machhw"
1176   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1177         (plus:SI (mult:SI (ashiftrt:SI
1178                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1179                            (const_int 16))
1180                           (ashiftrt:SI
1181                            (match_operand:SI 2 "gpc_reg_operand" "r")
1182                            (const_int 16)))
1183                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1184   "TARGET_MULHW"
1185   "machhw %0,%1,%2"
1186   [(set_attr "type" "halfmul")])
1188 (define_insn "*machhwuc"
1189   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1190         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1191                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1192                                        (const_int 16))
1193                                       (lshiftrt:SI
1194                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1195                                        (const_int 16)))
1196                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1197                     (const_int 0)))
1198    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1199         (plus:SI (mult:SI (lshiftrt:SI
1200                            (match_dup 1)
1201                            (const_int 16))
1202                           (lshiftrt:SI
1203                            (match_dup 2)
1204                            (const_int 16)))
1205                  (match_dup 4)))]
1206   "TARGET_MULHW"
1207   "machhwu. %0,%1,%2"
1208   [(set_attr "type" "halfmul")])
1210 (define_insn "*machhwu"
1211   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1212         (plus:SI (mult:SI (lshiftrt:SI
1213                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1214                            (const_int 16))
1215                           (lshiftrt:SI
1216                            (match_operand:SI 2 "gpc_reg_operand" "r")
1217                            (const_int 16)))
1218                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1219   "TARGET_MULHW"
1220   "machhwu %0,%1,%2"
1221   [(set_attr "type" "halfmul")])
1223 (define_insn "*maclhwc"
1224   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1225         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1226                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1227                                       (sign_extend:SI
1228                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1229                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1230                     (const_int 0)))
1231    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1232         (plus:SI (mult:SI (sign_extend:SI
1233                            (match_dup 1))
1234                           (sign_extend:SI
1235                            (match_dup 2)))
1236                  (match_dup 4)))]
1237   "TARGET_MULHW"
1238   "maclhw. %0,%1,%2"
1239   [(set_attr "type" "halfmul")])
1241 (define_insn "*maclhw"
1242   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1243         (plus:SI (mult:SI (sign_extend:SI
1244                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1245                           (sign_extend:SI
1246                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1247                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1248   "TARGET_MULHW"
1249   "maclhw %0,%1,%2"
1250   [(set_attr "type" "halfmul")])
1252 (define_insn "*maclhwuc"
1253   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1254         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1255                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1256                                       (zero_extend:SI
1257                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1258                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1259                     (const_int 0)))
1260    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1261         (plus:SI (mult:SI (zero_extend:SI
1262                            (match_dup 1))
1263                           (zero_extend:SI
1264                            (match_dup 2)))
1265                  (match_dup 4)))]
1266   "TARGET_MULHW"
1267   "maclhwu. %0,%1,%2"
1268   [(set_attr "type" "halfmul")])
1270 (define_insn "*maclhwu"
1271   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1272         (plus:SI (mult:SI (zero_extend:SI
1273                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1274                           (zero_extend:SI
1275                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1276                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1277   "TARGET_MULHW"
1278   "maclhwu %0,%1,%2"
1279   [(set_attr "type" "halfmul")])
1281 (define_insn "*nmacchwc"
1282   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1283         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1284                               (mult:SI (ashiftrt:SI
1285                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1286                                         (const_int 16))
1287                                        (sign_extend:SI
1288                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1289                     (const_int 0)))
1290    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1291         (minus:SI (match_dup 4)
1292                   (mult:SI (ashiftrt:SI
1293                             (match_dup 2)
1294                             (const_int 16))
1295                            (sign_extend:SI
1296                             (match_dup 1)))))]
1297   "TARGET_MULHW"
1298   "nmacchw. %0,%1,%2"
1299   [(set_attr "type" "halfmul")])
1301 (define_insn "*nmacchw"
1302   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1303         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1304                   (mult:SI (ashiftrt:SI
1305                             (match_operand:SI 2 "gpc_reg_operand" "r")
1306                             (const_int 16))
1307                            (sign_extend:SI
1308                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1309   "TARGET_MULHW"
1310   "nmacchw %0,%1,%2"
1311   [(set_attr "type" "halfmul")])
1313 (define_insn "*nmachhwc"
1314   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1315         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1316                               (mult:SI (ashiftrt:SI
1317                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1318                                         (const_int 16))
1319                                        (ashiftrt:SI
1320                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1321                                         (const_int 16))))
1322                     (const_int 0)))
1323    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1324         (minus:SI (match_dup 4)
1325                   (mult:SI (ashiftrt:SI
1326                             (match_dup 1)
1327                             (const_int 16))
1328                            (ashiftrt:SI
1329                             (match_dup 2)
1330                             (const_int 16)))))]
1331   "TARGET_MULHW"
1332   "nmachhw. %0,%1,%2"
1333   [(set_attr "type" "halfmul")])
1335 (define_insn "*nmachhw"
1336   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1337         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1338                   (mult:SI (ashiftrt:SI
1339                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1340                             (const_int 16))
1341                            (ashiftrt:SI
1342                             (match_operand:SI 2 "gpc_reg_operand" "r")
1343                             (const_int 16)))))]
1344   "TARGET_MULHW"
1345   "nmachhw %0,%1,%2"
1346   [(set_attr "type" "halfmul")])
1348 (define_insn "*nmaclhwc"
1349   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1350         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1351                               (mult:SI (sign_extend:SI
1352                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1353                                        (sign_extend:SI
1354                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1355                     (const_int 0)))
1356    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357         (minus:SI (match_dup 4)
1358                   (mult:SI (sign_extend:SI
1359                             (match_dup 1))
1360                            (sign_extend:SI
1361                             (match_dup 2)))))]
1362   "TARGET_MULHW"
1363   "nmaclhw. %0,%1,%2"
1364   [(set_attr "type" "halfmul")])
1366 (define_insn "*nmaclhw"
1367   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1368         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1369                   (mult:SI (sign_extend:SI
1370                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1371                            (sign_extend:SI
1372                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1373   "TARGET_MULHW"
1374   "nmaclhw %0,%1,%2"
1375   [(set_attr "type" "halfmul")])
1377 (define_insn "*mulchwc"
1378   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1379         (compare:CC (mult:SI (ashiftrt:SI
1380                               (match_operand:SI 2 "gpc_reg_operand" "r")
1381                               (const_int 16))
1382                              (sign_extend:SI
1383                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1384                     (const_int 0)))
1385    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1386         (mult:SI (ashiftrt:SI
1387                   (match_dup 2)
1388                   (const_int 16))
1389                  (sign_extend:SI
1390                   (match_dup 1))))]
1391   "TARGET_MULHW"
1392   "mulchw. %0,%1,%2"
1393   [(set_attr "type" "halfmul")])
1395 (define_insn "*mulchw"
1396   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1397         (mult:SI (ashiftrt:SI
1398                   (match_operand:SI 2 "gpc_reg_operand" "r")
1399                   (const_int 16))
1400                  (sign_extend:SI
1401                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1402   "TARGET_MULHW"
1403   "mulchw %0,%1,%2"
1404   [(set_attr "type" "halfmul")])
1406 (define_insn "*mulchwuc"
1407   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1408         (compare:CC (mult:SI (lshiftrt:SI
1409                               (match_operand:SI 2 "gpc_reg_operand" "r")
1410                               (const_int 16))
1411                              (zero_extend:SI
1412                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1413                     (const_int 0)))
1414    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1415         (mult:SI (lshiftrt:SI
1416                   (match_dup 2)
1417                   (const_int 16))
1418                  (zero_extend:SI
1419                   (match_dup 1))))]
1420   "TARGET_MULHW"
1421   "mulchwu. %0,%1,%2"
1422   [(set_attr "type" "halfmul")])
1424 (define_insn "*mulchwu"
1425   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1426         (mult:SI (lshiftrt:SI
1427                   (match_operand:SI 2 "gpc_reg_operand" "r")
1428                   (const_int 16))
1429                  (zero_extend:SI
1430                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1431   "TARGET_MULHW"
1432   "mulchwu %0,%1,%2"
1433   [(set_attr "type" "halfmul")])
1435 (define_insn "*mulhhwc"
1436   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1437         (compare:CC (mult:SI (ashiftrt:SI
1438                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1439                               (const_int 16))
1440                              (ashiftrt:SI
1441                               (match_operand:SI 2 "gpc_reg_operand" "r")
1442                               (const_int 16)))
1443                     (const_int 0)))
1444    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1445         (mult:SI (ashiftrt:SI
1446                   (match_dup 1)
1447                   (const_int 16))
1448                  (ashiftrt:SI
1449                   (match_dup 2)
1450                   (const_int 16))))]
1451   "TARGET_MULHW"
1452   "mulhhw. %0,%1,%2"
1453   [(set_attr "type" "halfmul")])
1455 (define_insn "*mulhhw"
1456   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1457         (mult:SI (ashiftrt:SI
1458                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1459                   (const_int 16))
1460                  (ashiftrt:SI
1461                   (match_operand:SI 2 "gpc_reg_operand" "r")
1462                   (const_int 16))))]
1463   "TARGET_MULHW"
1464   "mulhhw %0,%1,%2"
1465   [(set_attr "type" "halfmul")])
1467 (define_insn "*mulhhwuc"
1468   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1469         (compare:CC (mult:SI (lshiftrt:SI
1470                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1471                               (const_int 16))
1472                              (lshiftrt:SI
1473                               (match_operand:SI 2 "gpc_reg_operand" "r")
1474                               (const_int 16)))
1475                     (const_int 0)))
1476    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1477         (mult:SI (lshiftrt:SI
1478                   (match_dup 1)
1479                   (const_int 16))
1480                  (lshiftrt:SI
1481                   (match_dup 2)
1482                   (const_int 16))))]
1483   "TARGET_MULHW"
1484   "mulhhwu. %0,%1,%2"
1485   [(set_attr "type" "halfmul")])
1487 (define_insn "*mulhhwu"
1488   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1489         (mult:SI (lshiftrt:SI
1490                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1491                   (const_int 16))
1492                  (lshiftrt:SI
1493                   (match_operand:SI 2 "gpc_reg_operand" "r")
1494                   (const_int 16))))]
1495   "TARGET_MULHW"
1496   "mulhhwu %0,%1,%2"
1497   [(set_attr "type" "halfmul")])
1499 (define_insn "*mullhwc"
1500   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1501         (compare:CC (mult:SI (sign_extend:SI
1502                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1503                              (sign_extend:SI
1504                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1505                     (const_int 0)))
1506    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507         (mult:SI (sign_extend:SI
1508                   (match_dup 1))
1509                  (sign_extend:SI
1510                   (match_dup 2))))]
1511   "TARGET_MULHW"
1512   "mullhw. %0,%1,%2"
1513   [(set_attr "type" "halfmul")])
1515 (define_insn "*mullhw"
1516   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517         (mult:SI (sign_extend:SI
1518                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1519                  (sign_extend:SI
1520                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1521   "TARGET_MULHW"
1522   "mullhw %0,%1,%2"
1523   [(set_attr "type" "halfmul")])
1525 (define_insn "*mullhwuc"
1526   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1527         (compare:CC (mult:SI (zero_extend:SI
1528                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1529                              (zero_extend:SI
1530                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1531                     (const_int 0)))
1532    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1533         (mult:SI (zero_extend:SI
1534                   (match_dup 1))
1535                  (zero_extend:SI
1536                   (match_dup 2))))]
1537   "TARGET_MULHW"
1538   "mullhwu. %0,%1,%2"
1539   [(set_attr "type" "halfmul")])
1541 (define_insn "*mullhwu"
1542   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1543         (mult:SI (zero_extend:SI
1544                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1545                  (zero_extend:SI
1546                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1547   "TARGET_MULHW"
1548   "mullhwu %0,%1,%2"
1549   [(set_attr "type" "halfmul")])
1551 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1552 (define_insn "dlmzb"
1553   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1554         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1555                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1556                    UNSPEC_DLMZB_CR))
1557    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1558         (unspec:SI [(match_dup 1)
1559                     (match_dup 2)]
1560                    UNSPEC_DLMZB))]
1561   "TARGET_DLMZB"
1562   "dlmzb. %0,%1,%2")
1564 (define_expand "strlensi"
1565   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1566         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1567                     (match_operand:QI 2 "const_int_operand" "")
1568                     (match_operand 3 "const_int_operand" "")]
1569                    UNSPEC_DLMZB_STRLEN))
1570    (clobber (match_scratch:CC 4 "=x"))]
1571   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1573   rtx result = operands[0];
1574   rtx src = operands[1];
1575   rtx search_char = operands[2];
1576   rtx align = operands[3];
1577   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1578   rtx loop_label, end_label, mem, cr0, cond;
1579   if (search_char != const0_rtx
1580       || GET_CODE (align) != CONST_INT
1581       || INTVAL (align) < 8)
1582         FAIL;
1583   word1 = gen_reg_rtx (SImode);
1584   word2 = gen_reg_rtx (SImode);
1585   scratch_dlmzb = gen_reg_rtx (SImode);
1586   scratch_string = gen_reg_rtx (Pmode);
1587   loop_label = gen_label_rtx ();
1588   end_label = gen_label_rtx ();
1589   addr = force_reg (Pmode, XEXP (src, 0));
1590   emit_move_insn (scratch_string, addr);
1591   emit_label (loop_label);
1592   mem = change_address (src, SImode, scratch_string);
1593   emit_move_insn (word1, mem);
1594   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1595   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1596   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1597   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1598   emit_jump_insn (gen_rtx_SET (pc_rtx,
1599                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1600                                                      cond,
1601                                                      gen_rtx_LABEL_REF
1602                                                        (VOIDmode,
1603                                                         end_label),
1604                                                      pc_rtx)));
1605   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1606   emit_jump_insn (gen_rtx_SET (pc_rtx,
1607                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1608   emit_barrier ();
1609   emit_label (end_label);
1610   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1611   emit_insn (gen_subsi3 (result, scratch_string, addr));
1612   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1613   DONE;
1616 ;; Fixed-point arithmetic insns.
1618 (define_expand "add<mode>3"
1619   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1620         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1621                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1622   ""
1624   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1625     {
1626       rtx lo0 = gen_lowpart (SImode, operands[0]);
1627       rtx lo1 = gen_lowpart (SImode, operands[1]);
1628       rtx lo2 = gen_lowpart (SImode, operands[2]);
1629       rtx hi0 = gen_highpart (SImode, operands[0]);
1630       rtx hi1 = gen_highpart (SImode, operands[1]);
1631       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1633       if (!reg_or_short_operand (lo2, SImode))
1634         lo2 = force_reg (SImode, lo2);
1635       if (!adde_operand (hi2, SImode))
1636         hi2 = force_reg (SImode, hi2);
1638       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1639       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1640       DONE;
1641     }
1643   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1644     {
1645       rtx tmp = ((!can_create_pseudo_p ()
1646                   || rtx_equal_p (operands[0], operands[1]))
1647                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1649       HOST_WIDE_INT val = INTVAL (operands[2]);
1650       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1651       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1653       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1654         FAIL;
1656       /* The ordering here is important for the prolog expander.
1657          When space is allocated from the stack, adding 'low' first may
1658          produce a temporary deallocation (which would be bad).  */
1659       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1660       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1661       DONE;
1662     }
1665 (define_insn "*add<mode>3"
1666   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1667         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1668                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1669   ""
1670   "@
1671    add %0,%1,%2
1672    addi %0,%1,%2
1673    addis %0,%1,%v2"
1674   [(set_attr "type" "add")])
1676 (define_insn "addsi3_high"
1677   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1678         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1679                  (high:SI (match_operand 2 "" ""))))]
1680   "TARGET_MACHO && !TARGET_64BIT"
1681   "addis %0,%1,ha16(%2)"
1682   [(set_attr "type" "add")])
1684 (define_insn_and_split "*add<mode>3_dot"
1685   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1686         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1687                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1688                     (const_int 0)))
1689    (clobber (match_scratch:GPR 0 "=r,r"))]
1690   "<MODE>mode == Pmode"
1691   "@
1692    add. %0,%1,%2
1693    #"
1694   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1695   [(set (match_dup 0)
1696         (plus:GPR (match_dup 1)
1697                  (match_dup 2)))
1698    (set (match_dup 3)
1699         (compare:CC (match_dup 0)
1700                     (const_int 0)))]
1701   ""
1702   [(set_attr "type" "add")
1703    (set_attr "dot" "yes")
1704    (set_attr "length" "4,8")])
1706 (define_insn_and_split "*add<mode>3_dot2"
1707   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1708         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1709                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1710                     (const_int 0)))
1711    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1712         (plus:GPR (match_dup 1)
1713                   (match_dup 2)))]
1714   "<MODE>mode == Pmode"
1715   "@
1716    add. %0,%1,%2
1717    #"
1718   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1719   [(set (match_dup 0)
1720         (plus:GPR (match_dup 1)
1721                   (match_dup 2)))
1722    (set (match_dup 3)
1723         (compare:CC (match_dup 0)
1724                     (const_int 0)))]
1725   ""
1726   [(set_attr "type" "add")
1727    (set_attr "dot" "yes")
1728    (set_attr "length" "4,8")])
1730 (define_insn_and_split "*add<mode>3_imm_dot"
1731   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1732         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1733                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1734                     (const_int 0)))
1735    (clobber (match_scratch:GPR 0 "=r,r"))
1736    (clobber (reg:GPR CA_REGNO))]
1737   "<MODE>mode == Pmode"
1738   "@
1739    addic. %0,%1,%2
1740    #"
1741   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1742   [(set (match_dup 0)
1743         (plus:GPR (match_dup 1)
1744                   (match_dup 2)))
1745    (set (match_dup 3)
1746         (compare:CC (match_dup 0)
1747                     (const_int 0)))]
1748   ""
1749   [(set_attr "type" "add")
1750    (set_attr "dot" "yes")
1751    (set_attr "length" "4,8")])
1753 (define_insn_and_split "*add<mode>3_imm_dot2"
1754   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1755         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1756                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1757                     (const_int 0)))
1758    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1759         (plus:GPR (match_dup 1)
1760                   (match_dup 2)))
1761    (clobber (reg:GPR CA_REGNO))]
1762   "<MODE>mode == Pmode"
1763   "@
1764    addic. %0,%1,%2
1765    #"
1766   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1767   [(set (match_dup 0)
1768         (plus:GPR (match_dup 1)
1769                   (match_dup 2)))
1770    (set (match_dup 3)
1771         (compare:CC (match_dup 0)
1772                     (const_int 0)))]
1773   ""
1774   [(set_attr "type" "add")
1775    (set_attr "dot" "yes")
1776    (set_attr "length" "4,8")])
1778 ;; Split an add that we can't do in one insn into two insns, each of which
1779 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1780 ;; add should be last in case the result gets used in an address.
1782 (define_split
1783   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1784         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1785                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1786   ""
1787   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1788    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1790   HOST_WIDE_INT val = INTVAL (operands[2]);
1791   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1792   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1794   operands[4] = GEN_INT (low);
1795   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1796     operands[3] = GEN_INT (rest);
1797   else if (can_create_pseudo_p ())
1798     {
1799       operands[3] = gen_reg_rtx (DImode);
1800       emit_move_insn (operands[3], operands[2]);
1801       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1802       DONE;
1803     }
1804   else
1805     FAIL;
1809 (define_insn "add<mode>3_carry"
1810   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1811         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1812                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1813    (set (reg:P CA_REGNO)
1814         (ltu:P (plus:P (match_dup 1)
1815                        (match_dup 2))
1816                (match_dup 1)))]
1817   ""
1818   "add%I2c %0,%1,%2"
1819   [(set_attr "type" "add")])
1821 (define_insn "*add<mode>3_imm_carry_pos"
1822   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1823         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1824                 (match_operand:P 2 "short_cint_operand" "n")))
1825    (set (reg:P CA_REGNO)
1826         (geu:P (match_dup 1)
1827                (match_operand:P 3 "const_int_operand" "n")))]
1828   "INTVAL (operands[2]) > 0
1829    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1830   "addic %0,%1,%2"
1831   [(set_attr "type" "add")])
1833 (define_insn "*add<mode>3_imm_carry_0"
1834   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1835         (match_operand:P 1 "gpc_reg_operand" "r"))
1836    (set (reg:P CA_REGNO)
1837         (const_int 0))]
1838   ""
1839   "addic %0,%1,0"
1840   [(set_attr "type" "add")])
1842 (define_insn "*add<mode>3_imm_carry_m1"
1843   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1844         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1845                 (const_int -1)))
1846    (set (reg:P CA_REGNO)
1847         (ne:P (match_dup 1)
1848               (const_int 0)))]
1849   ""
1850   "addic %0,%1,-1"
1851   [(set_attr "type" "add")])
1853 (define_insn "*add<mode>3_imm_carry_neg"
1854   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1855         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1856                 (match_operand:P 2 "short_cint_operand" "n")))
1857    (set (reg:P CA_REGNO)
1858         (gtu:P (match_dup 1)
1859                (match_operand:P 3 "const_int_operand" "n")))]
1860   "INTVAL (operands[2]) < 0
1861    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1862   "addic %0,%1,%2"
1863   [(set_attr "type" "add")])
1866 (define_expand "add<mode>3_carry_in"
1867   [(parallel [
1868      (set (match_operand:GPR 0 "gpc_reg_operand")
1869           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1870                               (match_operand:GPR 2 "adde_operand"))
1871                     (reg:GPR CA_REGNO)))
1872      (clobber (reg:GPR CA_REGNO))])]
1873   ""
1875   if (operands[2] == const0_rtx)
1876     {
1877       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1878       DONE;
1879     }
1880   if (operands[2] == constm1_rtx)
1881     {
1882       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1883       DONE;
1884     }
1887 (define_insn "*add<mode>3_carry_in_internal"
1888   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1889         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1890                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1891                   (reg:GPR CA_REGNO)))
1892    (clobber (reg:GPR CA_REGNO))]
1893   ""
1894   "adde %0,%1,%2"
1895   [(set_attr "type" "add")])
1897 (define_insn "add<mode>3_carry_in_0"
1898   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1899         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1900                   (reg:GPR CA_REGNO)))
1901    (clobber (reg:GPR CA_REGNO))]
1902   ""
1903   "addze %0,%1"
1904   [(set_attr "type" "add")])
1906 (define_insn "add<mode>3_carry_in_m1"
1907   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1908         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1909                             (reg:GPR CA_REGNO))
1910                   (const_int -1)))
1911    (clobber (reg:GPR CA_REGNO))]
1912   ""
1913   "addme %0,%1"
1914   [(set_attr "type" "add")])
1917 (define_expand "one_cmpl<mode>2"
1918   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1919         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1920   ""
1922   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1923     {
1924       rs6000_split_logical (operands, NOT, false, false, false);
1925       DONE;
1926     }
1929 (define_insn "*one_cmpl<mode>2"
1930   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1931         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1932   ""
1933   "not %0,%1")
1935 (define_insn_and_split "*one_cmpl<mode>2_dot"
1936   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1937         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1938                     (const_int 0)))
1939    (clobber (match_scratch:GPR 0 "=r,r"))]
1940   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1941   "@
1942    not. %0,%1
1943    #"
1944   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1945   [(set (match_dup 0)
1946         (not:GPR (match_dup 1)))
1947    (set (match_dup 2)
1948         (compare:CC (match_dup 0)
1949                     (const_int 0)))]
1950   ""
1951   [(set_attr "type" "logical")
1952    (set_attr "dot" "yes")
1953    (set_attr "length" "4,8")])
1955 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1956   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1957         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1958                     (const_int 0)))
1959    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1960         (not:GPR (match_dup 1)))]
1961   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1962   "@
1963    not. %0,%1
1964    #"
1965   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1966   [(set (match_dup 0)
1967         (not:GPR (match_dup 1)))
1968    (set (match_dup 2)
1969         (compare:CC (match_dup 0)
1970                     (const_int 0)))]
1971   ""
1972   [(set_attr "type" "logical")
1973    (set_attr "dot" "yes")
1974    (set_attr "length" "4,8")])
1977 (define_expand "sub<mode>3"
1978   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1979         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1980                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1981   ""
1983   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1984     {
1985       rtx lo0 = gen_lowpart (SImode, operands[0]);
1986       rtx lo1 = gen_lowpart (SImode, operands[1]);
1987       rtx lo2 = gen_lowpart (SImode, operands[2]);
1988       rtx hi0 = gen_highpart (SImode, operands[0]);
1989       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1990       rtx hi2 = gen_highpart (SImode, operands[2]);
1992       if (!reg_or_short_operand (lo1, SImode))
1993         lo1 = force_reg (SImode, lo1);
1994       if (!adde_operand (hi1, SImode))
1995         hi1 = force_reg (SImode, hi1);
1997       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1998       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1999       DONE;
2000     }
2002   if (short_cint_operand (operands[1], <MODE>mode))
2003     {
2004       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2005       DONE;
2006     }
2009 (define_insn "*subf<mode>3"
2010   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2011         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2012                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2013   ""
2014   "subf %0,%1,%2"
2015   [(set_attr "type" "add")])
2017 (define_insn_and_split "*subf<mode>3_dot"
2018   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2019         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2020                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2021                     (const_int 0)))
2022    (clobber (match_scratch:GPR 0 "=r,r"))]
2023   "<MODE>mode == Pmode"
2024   "@
2025    subf. %0,%1,%2
2026    #"
2027   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2028   [(set (match_dup 0)
2029         (minus:GPR (match_dup 2)
2030                    (match_dup 1)))
2031    (set (match_dup 3)
2032         (compare:CC (match_dup 0)
2033                     (const_int 0)))]
2034   ""
2035   [(set_attr "type" "add")
2036    (set_attr "dot" "yes")
2037    (set_attr "length" "4,8")])
2039 (define_insn_and_split "*subf<mode>3_dot2"
2040   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2041         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2042                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2043                     (const_int 0)))
2044    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2045         (minus:GPR (match_dup 2)
2046                    (match_dup 1)))]
2047   "<MODE>mode == Pmode"
2048   "@
2049    subf. %0,%1,%2
2050    #"
2051   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2052   [(set (match_dup 0)
2053         (minus:GPR (match_dup 2)
2054                    (match_dup 1)))
2055    (set (match_dup 3)
2056         (compare:CC (match_dup 0)
2057                     (const_int 0)))]
2058   ""
2059   [(set_attr "type" "add")
2060    (set_attr "dot" "yes")
2061    (set_attr "length" "4,8")])
2063 (define_insn "subf<mode>3_imm"
2064   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2065         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2066                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2067    (clobber (reg:GPR CA_REGNO))]
2068   ""
2069   "subfic %0,%1,%2"
2070   [(set_attr "type" "add")])
2073 (define_insn "subf<mode>3_carry"
2074   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2075         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2076                  (match_operand:P 1 "gpc_reg_operand" "r")))
2077    (set (reg:P CA_REGNO)
2078         (leu:P (match_dup 1)
2079                (match_dup 2)))]
2080   ""
2081   "subf%I2c %0,%1,%2"
2082   [(set_attr "type" "add")])
2084 (define_insn "*subf<mode>3_imm_carry_0"
2085   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2086         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2087    (set (reg:P CA_REGNO)
2088         (eq:P (match_dup 1)
2089               (const_int 0)))]
2090   ""
2091   "subfic %0,%1,0"
2092   [(set_attr "type" "add")])
2094 (define_insn "*subf<mode>3_imm_carry_m1"
2095   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2096         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2097    (set (reg:P CA_REGNO)
2098         (const_int 1))]
2099   ""
2100   "subfic %0,%1,-1"
2101   [(set_attr "type" "add")])
2104 (define_expand "subf<mode>3_carry_in"
2105   [(parallel [
2106      (set (match_operand:GPR 0 "gpc_reg_operand")
2107           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2108                               (reg:GPR CA_REGNO))
2109                     (match_operand:GPR 2 "adde_operand")))
2110      (clobber (reg:GPR CA_REGNO))])]
2111   ""
2113   if (operands[2] == const0_rtx)
2114     {
2115       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2116       DONE;
2117     }
2118   if (operands[2] == constm1_rtx)
2119     {
2120       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2121       DONE;
2122     }
2125 (define_insn "*subf<mode>3_carry_in_internal"
2126   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2127         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2128                             (reg:GPR CA_REGNO))
2129                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2130    (clobber (reg:GPR CA_REGNO))]
2131   ""
2132   "subfe %0,%1,%2"
2133   [(set_attr "type" "add")])
2135 (define_insn "subf<mode>3_carry_in_0"
2136   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2138                   (reg:GPR CA_REGNO)))
2139    (clobber (reg:GPR CA_REGNO))]
2140   ""
2141   "subfze %0,%1"
2142   [(set_attr "type" "add")])
2144 (define_insn "subf<mode>3_carry_in_m1"
2145   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2146         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2147                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2148                   (const_int -2)))
2149    (clobber (reg:GPR CA_REGNO))]
2150   ""
2151   "subfme %0,%1"
2152   [(set_attr "type" "add")])
2154 (define_insn "subf<mode>3_carry_in_xx"
2155   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2156         (plus:GPR (reg:GPR CA_REGNO)
2157                   (const_int -1)))
2158    (clobber (reg:GPR CA_REGNO))]
2159   ""
2160   "subfe %0,%0,%0"
2161   [(set_attr "type" "add")])
2164 (define_insn "neg<mode>2"
2165   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2166         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2167   ""
2168   "neg %0,%1"
2169   [(set_attr "type" "add")])
2171 (define_insn_and_split "*neg<mode>2_dot"
2172   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2173         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2174                     (const_int 0)))
2175    (clobber (match_scratch:GPR 0 "=r,r"))]
2176   "<MODE>mode == Pmode"
2177   "@
2178    neg. %0,%1
2179    #"
2180   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2181   [(set (match_dup 0)
2182         (neg:GPR (match_dup 1)))
2183    (set (match_dup 2)
2184         (compare:CC (match_dup 0)
2185                     (const_int 0)))]
2186   ""
2187   [(set_attr "type" "add")
2188    (set_attr "dot" "yes")
2189    (set_attr "length" "4,8")])
2191 (define_insn_and_split "*neg<mode>2_dot2"
2192   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2193         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2194                     (const_int 0)))
2195    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2196         (neg:GPR (match_dup 1)))]
2197   "<MODE>mode == Pmode"
2198   "@
2199    neg. %0,%1
2200    #"
2201   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2202   [(set (match_dup 0)
2203         (neg:GPR (match_dup 1)))
2204    (set (match_dup 2)
2205         (compare:CC (match_dup 0)
2206                     (const_int 0)))]
2207   ""
2208   [(set_attr "type" "add")
2209    (set_attr "dot" "yes")
2210    (set_attr "length" "4,8")])
2213 (define_insn "clz<mode>2"
2214   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2215         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2216   ""
2217   "cntlz<wd> %0,%1"
2218   [(set_attr "type" "cntlz")])
2220 (define_expand "ctz<mode>2"
2221    [(set (match_operand:GPR 0 "gpc_reg_operand")
2222          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2223   ""
2225   if (TARGET_CTZ)
2226     {
2227       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2228       DONE;
2229     }
2231   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2232   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2233   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2235   if (TARGET_POPCNTD)
2236     {
2237       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2238       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2239       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2240       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2241     }
2242   else
2243     {
2244       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2245       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2246       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2247       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2248     }
2250   DONE;
2253 (define_insn "ctz<mode>2_hw"
2254   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2255         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2256   "TARGET_CTZ"
2257   "cnttz<wd> %0,%1"
2258   [(set_attr "type" "cntlz")])
2260 (define_expand "ffs<mode>2"
2261   [(set (match_operand:GPR 0 "gpc_reg_operand")
2262         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2263   ""
2265   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2266   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2267   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2268   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2269   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2270   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2271   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2272   DONE;
2276 (define_expand "popcount<mode>2"
2277   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2278         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2279   "TARGET_POPCNTB || TARGET_POPCNTD"
2281   rs6000_emit_popcount (operands[0], operands[1]);
2282   DONE;
2285 (define_insn "popcntb<mode>2"
2286   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2288                     UNSPEC_POPCNTB))]
2289   "TARGET_POPCNTB"
2290   "popcntb %0,%1"
2291   [(set_attr "type" "popcnt")])
2293 (define_insn "popcntd<mode>2"
2294   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2296   "TARGET_POPCNTD"
2297   "popcnt<wd> %0,%1"
2298   [(set_attr "type" "popcnt")])
2301 (define_expand "parity<mode>2"
2302   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2303         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2304   "TARGET_POPCNTB"
2306   rs6000_emit_parity (operands[0], operands[1]);
2307   DONE;
2310 (define_insn "parity<mode>2_cmpb"
2311   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2312         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2313   "TARGET_CMPB && TARGET_POPCNTB"
2314   "prty<wd> %0,%1"
2315   [(set_attr "type" "popcnt")])
2317 (define_insn "cmpb<mode>3"
2318   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2319         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2320                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2321   "TARGET_CMPB"
2322   "cmpb %0,%1,%2"
2323   [(set_attr "type" "cmp")])
2325 ;; Since the hardware zeros the upper part of the register, save generating the
2326 ;; AND immediate if we are converting to unsigned
2327 (define_insn "*bswaphi2_extenddi"
2328   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2329         (zero_extend:DI
2330          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2331   "TARGET_POWERPC64"
2332   "lhbrx %0,%y1"
2333   [(set_attr "length" "4")
2334    (set_attr "type" "load")])
2336 (define_insn "*bswaphi2_extendsi"
2337   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2338         (zero_extend:SI
2339          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2340   ""
2341   "lhbrx %0,%y1"
2342   [(set_attr "length" "4")
2343    (set_attr "type" "load")])
2345 (define_expand "bswaphi2"
2346   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2347                    (bswap:HI
2348                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2349               (clobber (match_scratch:SI 2 ""))])]
2350   ""
2352   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2353     operands[1] = force_reg (HImode, operands[1]);
2356 (define_insn "bswaphi2_internal"
2357   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2358         (bswap:HI
2359          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2360    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2361   ""
2362   "@
2363    lhbrx %0,%y1
2364    sthbrx %1,%y0
2365    #"
2366   [(set_attr "length" "4,4,12")
2367    (set_attr "type" "load,store,*")])
2369 (define_split
2370   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2371         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2372    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2373   "reload_completed"
2374   [(set (match_dup 3)
2375         (and:SI (lshiftrt:SI (match_dup 4)
2376                              (const_int 8))
2377                 (const_int 255)))
2378    (set (match_dup 2)
2379         (and:SI (ashift:SI (match_dup 4)
2380                            (const_int 8))
2381                 (const_int 65280)))             ;; 0xff00
2382    (set (match_dup 3)
2383         (ior:SI (match_dup 3)
2384                 (match_dup 2)))]
2385   "
2387   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2388   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2391 (define_insn "*bswapsi2_extenddi"
2392   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2393         (zero_extend:DI
2394          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2395   "TARGET_POWERPC64"
2396   "lwbrx %0,%y1"
2397   [(set_attr "length" "4")
2398    (set_attr "type" "load")])
2400 (define_expand "bswapsi2"
2401   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2402         (bswap:SI
2403          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2404   ""
2406   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2407     operands[1] = force_reg (SImode, operands[1]);
2410 (define_insn "*bswapsi2_internal"
2411   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2412         (bswap:SI
2413          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2414   ""
2415   "@
2416    lwbrx %0,%y1
2417    stwbrx %1,%y0
2418    #"
2419   [(set_attr "length" "4,4,12")
2420    (set_attr "type" "load,store,*")])
2422 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2423 ;; zero_extract insns do not change for -mlittle.
2424 (define_split
2425   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2426         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2427   "reload_completed"
2428   [(set (match_dup 0)                                   ; DABC
2429         (rotate:SI (match_dup 1)
2430                    (const_int 24)))
2431    (set (match_dup 0)                                   ; DCBC
2432         (ior:SI (and:SI (ashift:SI (match_dup 1)
2433                                    (const_int 8))
2434                         (const_int 16711680))
2435                 (and:SI (match_dup 0)
2436                         (const_int -16711681))))
2437    (set (match_dup 0)                                   ; DCBA
2438         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2439                                      (const_int 24))
2440                         (const_int 255))
2441                 (and:SI (match_dup 0)
2442                         (const_int -256))))
2444   ]
2445   "")
2447 (define_expand "bswapdi2"
2448   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2449                    (bswap:DI
2450                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2451               (clobber (match_scratch:DI 2 ""))
2452               (clobber (match_scratch:DI 3 ""))])]
2453   ""
2455   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2456     operands[1] = force_reg (DImode, operands[1]);
2458   if (!TARGET_POWERPC64)
2459     {
2460       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2461          that uses 64-bit registers needs the same scratch registers as 64-bit
2462          mode.  */
2463       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2464       DONE;
2465     }
2468 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2469 (define_insn "*bswapdi2_ldbrx"
2470   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2471         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2472    (clobber (match_scratch:DI 2 "=X,X,&r"))
2473    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2474   "TARGET_POWERPC64 && TARGET_LDBRX
2475    && (REG_P (operands[0]) || REG_P (operands[1]))"
2476   "@
2477    ldbrx %0,%y1
2478    stdbrx %1,%y0
2479    #"
2480   [(set_attr "length" "4,4,36")
2481    (set_attr "type" "load,store,*")])
2483 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2484 (define_insn "*bswapdi2_64bit"
2485   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2486         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2487    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2488    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2489   "TARGET_POWERPC64 && !TARGET_LDBRX
2490    && (REG_P (operands[0]) || REG_P (operands[1]))
2491    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2492    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2493   "#"
2494   [(set_attr "length" "16,12,36")])
2496 (define_split
2497   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2498         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2499    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2500    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2501   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2502   [(const_int 0)]
2503   "
2505   rtx dest   = operands[0];
2506   rtx src    = operands[1];
2507   rtx op2    = operands[2];
2508   rtx op3    = operands[3];
2509   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2510                                     BYTES_BIG_ENDIAN ? 4 : 0);
2511   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2512                                      BYTES_BIG_ENDIAN ? 4 : 0);
2513   rtx addr1;
2514   rtx addr2;
2515   rtx word1;
2516   rtx word2;
2518   addr1 = XEXP (src, 0);
2519   if (GET_CODE (addr1) == PLUS)
2520     {
2521       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2522       if (TARGET_AVOID_XFORM)
2523         {
2524           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2525           addr2 = op2;
2526         }
2527       else
2528         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2529     }
2530   else if (TARGET_AVOID_XFORM)
2531     {
2532       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2533       addr2 = op2;
2534     }
2535   else
2536     {
2537       emit_move_insn (op2, GEN_INT (4));
2538       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2539     }
2541   word1 = change_address (src, SImode, addr1);
2542   word2 = change_address (src, SImode, addr2);
2544   if (BYTES_BIG_ENDIAN)
2545     {
2546       emit_insn (gen_bswapsi2 (op3_32, word2));
2547       emit_insn (gen_bswapsi2 (dest_32, word1));
2548     }
2549   else
2550     {
2551       emit_insn (gen_bswapsi2 (op3_32, word1));
2552       emit_insn (gen_bswapsi2 (dest_32, word2));
2553     }
2555   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2556   emit_insn (gen_iordi3 (dest, dest, op3));
2557   DONE;
2560 (define_split
2561   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2562         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2563    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2564    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2565   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2566   [(const_int 0)]
2567   "
2569   rtx dest   = operands[0];
2570   rtx src    = operands[1];
2571   rtx op2    = operands[2];
2572   rtx op3    = operands[3];
2573   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2574                                     BYTES_BIG_ENDIAN ? 4 : 0);
2575   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2576                                     BYTES_BIG_ENDIAN ? 4 : 0);
2577   rtx addr1;
2578   rtx addr2;
2579   rtx word1;
2580   rtx word2;
2582   addr1 = XEXP (dest, 0);
2583   if (GET_CODE (addr1) == PLUS)
2584     {
2585       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2586       if (TARGET_AVOID_XFORM)
2587         {
2588           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2589           addr2 = op2;
2590         }
2591       else
2592         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2593     }
2594   else if (TARGET_AVOID_XFORM)
2595     {
2596       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2597       addr2 = op2;
2598     }
2599   else
2600     {
2601       emit_move_insn (op2, GEN_INT (4));
2602       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2603     }
2605   word1 = change_address (dest, SImode, addr1);
2606   word2 = change_address (dest, SImode, addr2);
2608   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2610   if (BYTES_BIG_ENDIAN)
2611     {
2612       emit_insn (gen_bswapsi2 (word1, src_si));
2613       emit_insn (gen_bswapsi2 (word2, op3_si));
2614     }
2615   else
2616     {
2617       emit_insn (gen_bswapsi2 (word2, src_si));
2618       emit_insn (gen_bswapsi2 (word1, op3_si));
2619     }
2620   DONE;
2623 (define_split
2624   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2625         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2626    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2627    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2628   "TARGET_POWERPC64 && reload_completed"
2629   [(const_int 0)]
2630   "
2632   rtx dest    = operands[0];
2633   rtx src     = operands[1];
2634   rtx op2     = operands[2];
2635   rtx op3     = operands[3];
2636   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2637   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2638   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2639   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2640   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2642   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2643   emit_insn (gen_bswapsi2 (dest_si, src_si));
2644   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2645   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2646   emit_insn (gen_iordi3 (dest, dest, op3));
2647   DONE;
2650 (define_insn "bswapdi2_32bit"
2651   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2652         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2653    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2654   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2655   "#"
2656   [(set_attr "length" "16,12,36")])
2658 (define_split
2659   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2660         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2661    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2662   "!TARGET_POWERPC64 && reload_completed"
2663   [(const_int 0)]
2664   "
2666   rtx dest  = operands[0];
2667   rtx src   = operands[1];
2668   rtx op2   = operands[2];
2669   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2670   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2671   rtx addr1;
2672   rtx addr2;
2673   rtx word1;
2674   rtx word2;
2676   addr1 = XEXP (src, 0);
2677   if (GET_CODE (addr1) == PLUS)
2678     {
2679       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2680       if (TARGET_AVOID_XFORM
2681           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2682         {
2683           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2684           addr2 = op2;
2685         }
2686       else
2687         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2688     }
2689   else if (TARGET_AVOID_XFORM
2690            || REGNO (addr1) == REGNO (dest2))
2691     {
2692       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2693       addr2 = op2;
2694     }
2695   else
2696     {
2697       emit_move_insn (op2, GEN_INT (4));
2698       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2699     }
2701   word1 = change_address (src, SImode, addr1);
2702   word2 = change_address (src, SImode, addr2);
2704   emit_insn (gen_bswapsi2 (dest2, word1));
2705   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2706      thus allowing us to omit an early clobber on the output.  */
2707   emit_insn (gen_bswapsi2 (dest1, word2));
2708   DONE;
2711 (define_split
2712   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2713         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2714    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2715   "!TARGET_POWERPC64 && reload_completed"
2716   [(const_int 0)]
2717   "
2719   rtx dest = operands[0];
2720   rtx src  = operands[1];
2721   rtx op2  = operands[2];
2722   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2723   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2724   rtx addr1;
2725   rtx addr2;
2726   rtx word1;
2727   rtx word2;
2729   addr1 = XEXP (dest, 0);
2730   if (GET_CODE (addr1) == PLUS)
2731     {
2732       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2733       if (TARGET_AVOID_XFORM)
2734         {
2735           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2736           addr2 = op2;
2737         }
2738       else
2739         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2740     }
2741   else if (TARGET_AVOID_XFORM)
2742     {
2743       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2744       addr2 = op2;
2745     }
2746   else
2747     {
2748       emit_move_insn (op2, GEN_INT (4));
2749       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2750     }
2752   word1 = change_address (dest, SImode, addr1);
2753   word2 = change_address (dest, SImode, addr2);
2755   emit_insn (gen_bswapsi2 (word2, src1));
2756   emit_insn (gen_bswapsi2 (word1, src2));
2757   DONE;
2760 (define_split
2761   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2762         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2763    (clobber (match_operand:SI 2 "" ""))]
2764   "!TARGET_POWERPC64 && reload_completed"
2765   [(const_int 0)]
2766   "
2768   rtx dest  = operands[0];
2769   rtx src   = operands[1];
2770   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2771   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2772   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2773   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2775   emit_insn (gen_bswapsi2 (dest1, src2));
2776   emit_insn (gen_bswapsi2 (dest2, src1));
2777   DONE;
2781 (define_insn "mul<mode>3"
2782   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2783         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2784                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2785   ""
2786   "@
2787    mull<wd> %0,%1,%2
2788    mulli %0,%1,%2"
2789    [(set_attr "type" "mul")
2790     (set (attr "size")
2791       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2792                 (const_string "8")
2793              (match_operand:GPR 2 "short_cint_operand" "")
2794                 (const_string "16")]
2795         (const_string "<bits>")))])
2797 (define_insn_and_split "*mul<mode>3_dot"
2798   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2799         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2800                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2801                     (const_int 0)))
2802    (clobber (match_scratch:GPR 0 "=r,r"))]
2803   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2804   "@
2805    mull<wd>. %0,%1,%2
2806    #"
2807   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2808   [(set (match_dup 0)
2809         (mult:GPR (match_dup 1)
2810                   (match_dup 2)))
2811    (set (match_dup 3)
2812         (compare:CC (match_dup 0)
2813                     (const_int 0)))]
2814   ""
2815   [(set_attr "type" "mul")
2816    (set_attr "size" "<bits>")
2817    (set_attr "dot" "yes")
2818    (set_attr "length" "4,8")])
2820 (define_insn_and_split "*mul<mode>3_dot2"
2821   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2822         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2823                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2824                     (const_int 0)))
2825    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2826         (mult:GPR (match_dup 1)
2827                   (match_dup 2)))]
2828   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2829   "@
2830    mull<wd>. %0,%1,%2
2831    #"
2832   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2833   [(set (match_dup 0)
2834         (mult:GPR (match_dup 1)
2835                   (match_dup 2)))
2836    (set (match_dup 3)
2837         (compare:CC (match_dup 0)
2838                     (const_int 0)))]
2839   ""
2840   [(set_attr "type" "mul")
2841    (set_attr "size" "<bits>")
2842    (set_attr "dot" "yes")
2843    (set_attr "length" "4,8")])
2846 (define_expand "<su>mul<mode>3_highpart"
2847   [(set (match_operand:GPR 0 "gpc_reg_operand")
2848         (subreg:GPR
2849           (mult:<DMODE> (any_extend:<DMODE>
2850                           (match_operand:GPR 1 "gpc_reg_operand"))
2851                         (any_extend:<DMODE>
2852                           (match_operand:GPR 2 "gpc_reg_operand")))
2853          0))]
2854   ""
2856   if (<MODE>mode == SImode && TARGET_POWERPC64)
2857     {
2858       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2859                                              operands[2]));
2860       DONE;
2861     }
2863   if (!WORDS_BIG_ENDIAN)
2864     {
2865       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2866                                                  operands[2]));
2867       DONE;
2868     }
2871 (define_insn "*<su>mul<mode>3_highpart"
2872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2873         (subreg:GPR
2874           (mult:<DMODE> (any_extend:<DMODE>
2875                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2876                         (any_extend:<DMODE>
2877                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2878          0))]
2879   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2880   "mulh<wd><u> %0,%1,%2"
2881   [(set_attr "type" "mul")
2882    (set_attr "size" "<bits>")])
2884 (define_insn "<su>mulsi3_highpart_le"
2885   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2886         (subreg:SI
2887           (mult:DI (any_extend:DI
2888                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2889                    (any_extend:DI
2890                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2891          4))]
2892   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2893   "mulhw<u> %0,%1,%2"
2894   [(set_attr "type" "mul")])
2896 (define_insn "<su>muldi3_highpart_le"
2897   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2898         (subreg:DI
2899           (mult:TI (any_extend:TI
2900                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2901                    (any_extend:TI
2902                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2903          8))]
2904   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2905   "mulhd<u> %0,%1,%2"
2906   [(set_attr "type" "mul")
2907    (set_attr "size" "64")])
2909 (define_insn "<su>mulsi3_highpart_64"
2910   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2911         (truncate:SI
2912           (lshiftrt:DI
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             (const_int 32))))]
2918   "TARGET_POWERPC64"
2919   "mulhw<u> %0,%1,%2"
2920   [(set_attr "type" "mul")])
2922 (define_expand "<u>mul<mode><dmode>3"
2923   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2924         (mult:<DMODE> (any_extend:<DMODE>
2925                         (match_operand:GPR 1 "gpc_reg_operand"))
2926                       (any_extend:<DMODE>
2927                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2928   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2930   rtx l = gen_reg_rtx (<MODE>mode);
2931   rtx h = gen_reg_rtx (<MODE>mode);
2932   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2933   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2934   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2935   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2936   DONE;
2939 (define_insn "*maddld4"
2940   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2941         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2942                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2943                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2944   "TARGET_MADDLD"
2945   "maddld %0,%1,%2,%3"
2946   [(set_attr "type" "mul")])
2948 (define_insn "udiv<mode>3"
2949   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2950         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2951                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2952   ""
2953   "div<wd>u %0,%1,%2"
2954   [(set_attr "type" "div")
2955    (set_attr "size" "<bits>")])
2958 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2959 ;; modulus.  If it isn't a power of two, force operands into register and do
2960 ;; a normal divide.
2961 (define_expand "div<mode>3"
2962   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2963         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2964                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2965   ""
2967   if (CONST_INT_P (operands[2])
2968       && INTVAL (operands[2]) > 0
2969       && exact_log2 (INTVAL (operands[2])) >= 0)
2970     {
2971       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2972       DONE;
2973     }
2975   operands[2] = force_reg (<MODE>mode, operands[2]);
2978 (define_insn "*div<mode>3"
2979   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2980         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2981                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2982   ""
2983   "div<wd> %0,%1,%2"
2984   [(set_attr "type" "div")
2985    (set_attr "size" "<bits>")])
2987 (define_insn "div<mode>3_sra"
2988   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2989         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2990                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2991    (clobber (reg:GPR CA_REGNO))]
2992   ""
2993   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2994   [(set_attr "type" "two")
2995    (set_attr "length" "8")])
2997 (define_insn_and_split "*div<mode>3_sra_dot"
2998   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2999         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3000                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3001                     (const_int 0)))
3002    (clobber (match_scratch:GPR 0 "=r,r"))
3003    (clobber (reg:GPR CA_REGNO))]
3004   "<MODE>mode == Pmode"
3005   "@
3006    sra<wd>i %0,%1,%p2\;addze. %0,%0
3007    #"
3008   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3009   [(parallel [(set (match_dup 0)
3010                    (div:GPR (match_dup 1)
3011                             (match_dup 2)))
3012               (clobber (reg:GPR CA_REGNO))])
3013    (set (match_dup 3)
3014         (compare:CC (match_dup 0)
3015                     (const_int 0)))]
3016   ""
3017   [(set_attr "type" "two")
3018    (set_attr "length" "8,12")
3019    (set_attr "cell_micro" "not")])
3021 (define_insn_and_split "*div<mode>3_sra_dot2"
3022   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3023         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3024                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3025                     (const_int 0)))
3026    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3027         (div:GPR (match_dup 1)
3028                  (match_dup 2)))
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_expand "mod<mode>3"
3048   [(set (match_operand:GPR 0 "gpc_reg_operand")
3049         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3050                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3051   ""
3053   int i;
3054   rtx temp1;
3055   rtx temp2;
3057   if (GET_CODE (operands[2]) != CONST_INT
3058       || INTVAL (operands[2]) <= 0
3059       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3060     {
3061       if (!TARGET_MODULO)
3062         FAIL;
3064       operands[2] = force_reg (<MODE>mode, operands[2]);
3065     }
3066   else
3067     {
3068       temp1 = gen_reg_rtx (<MODE>mode);
3069       temp2 = gen_reg_rtx (<MODE>mode);
3071       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3072       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3073       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3074       DONE;
3075     }
3078 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3079 ;; mod, prefer putting the result of mod into a different register
3080 (define_insn "*mod<mode>3"
3081   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3082         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3083                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3084   "TARGET_MODULO"
3085   "mods<wd> %0,%1,%2"
3086   [(set_attr "type" "div")
3087    (set_attr "size" "<bits>")])
3090 (define_insn "umod<mode>3"
3091   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3092         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3093                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3094   "TARGET_MODULO"
3095   "modu<wd> %0,%1,%2"
3096   [(set_attr "type" "div")
3097    (set_attr "size" "<bits>")])
3099 ;; On machines with modulo support, do a combined div/mod the old fashioned
3100 ;; method, since the multiply/subtract is faster than doing the mod instruction
3101 ;; after a divide.
3103 (define_peephole2
3104   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3105         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3106                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3107    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3108         (mod:GPR (match_dup 1)
3109                  (match_dup 2)))]
3110   "TARGET_MODULO
3111    && ! reg_mentioned_p (operands[0], operands[1])
3112    && ! reg_mentioned_p (operands[0], operands[2])
3113    && ! reg_mentioned_p (operands[3], operands[1])
3114    && ! reg_mentioned_p (operands[3], operands[2])"
3115   [(set (match_dup 0)
3116         (div:GPR (match_dup 1)
3117                  (match_dup 2)))
3118    (set (match_dup 3)
3119         (mult:GPR (match_dup 0)
3120                   (match_dup 2)))
3121    (set (match_dup 3)
3122         (minus:GPR (match_dup 1)
3123                    (match_dup 3)))])
3125 (define_peephole2
3126   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3127         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3128                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3129    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3130         (umod:GPR (match_dup 1)
3131                   (match_dup 2)))]
3132   "TARGET_MODULO
3133    && ! reg_mentioned_p (operands[0], operands[1])
3134    && ! reg_mentioned_p (operands[0], operands[2])
3135    && ! reg_mentioned_p (operands[3], operands[1])
3136    && ! reg_mentioned_p (operands[3], operands[2])"
3137   [(set (match_dup 0)
3138         (div:GPR (match_dup 1)
3139                  (match_dup 2)))
3140    (set (match_dup 3)
3141         (mult:GPR (match_dup 0)
3142                   (match_dup 2)))
3143    (set (match_dup 3)
3144         (minus:GPR (match_dup 1)
3145                    (match_dup 3)))])
3148 ;; Logical instructions
3149 ;; The logical instructions are mostly combined by using match_operator,
3150 ;; but the plain AND insns are somewhat different because there is no
3151 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3152 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3154 (define_expand "and<mode>3"
3155   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3156         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3157                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3158   ""
3160   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3161     {
3162       rs6000_split_logical (operands, AND, false, false, false);
3163       DONE;
3164     }
3166   if (CONST_INT_P (operands[2]))
3167     {
3168       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3169         {
3170           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3171           DONE;
3172         }
3174       if (logical_const_operand (operands[2], <MODE>mode)
3175           && rs6000_gen_cell_microcode)
3176         {
3177           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3178           DONE;
3179         }
3181       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3182         {
3183           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3184           DONE;
3185         }
3187       operands[2] = force_reg (<MODE>mode, operands[2]);
3188     }
3192 (define_insn "and<mode>3_imm"
3193   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3194         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3195                  (match_operand:GPR 2 "logical_const_operand" "n")))
3196    (clobber (match_scratch:CC 3 "=x"))]
3197   "rs6000_gen_cell_microcode
3198    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3199   "andi%e2. %0,%1,%u2"
3200   [(set_attr "type" "logical")
3201    (set_attr "dot" "yes")])
3203 (define_insn_and_split "*and<mode>3_imm_dot"
3204   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3205         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3206                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3207                     (const_int 0)))
3208    (clobber (match_scratch:GPR 0 "=r,r"))
3209    (clobber (match_scratch:CC 4 "=X,x"))]
3210   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3211    && rs6000_gen_cell_microcode
3212    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3213   "@
3214    andi%e2. %0,%1,%u2
3215    #"
3216   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3217   [(parallel [(set (match_dup 0)
3218                    (and:GPR (match_dup 1)
3219                             (match_dup 2)))
3220               (clobber (match_dup 4))])
3221    (set (match_dup 3)
3222         (compare:CC (match_dup 0)
3223                     (const_int 0)))]
3224   ""
3225   [(set_attr "type" "logical")
3226    (set_attr "dot" "yes")
3227    (set_attr "length" "4,8")])
3229 (define_insn_and_split "*and<mode>3_imm_dot2"
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    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3235         (and:GPR (match_dup 1)
3236                  (match_dup 2)))
3237    (clobber (match_scratch:CC 4 "=X,x"))]
3238   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3239    && rs6000_gen_cell_microcode
3240    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3241   "@
3242    andi%e2. %0,%1,%u2
3243    #"
3244   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3245   [(parallel [(set (match_dup 0)
3246                    (and:GPR (match_dup 1)
3247                             (match_dup 2)))
3248               (clobber (match_dup 4))])
3249    (set (match_dup 3)
3250         (compare:CC (match_dup 0)
3251                     (const_int 0)))]
3252   ""
3253   [(set_attr "type" "logical")
3254    (set_attr "dot" "yes")
3255    (set_attr "length" "4,8")])
3257 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3258   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3259         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3260                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3261                     (const_int 0)))
3262    (clobber (match_scratch:GPR 0 "=r,r"))]
3263   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3264    && rs6000_gen_cell_microcode
3265    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3266   "@
3267    andi%e2. %0,%1,%u2
3268    #"
3269   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3270   [(set (match_dup 0)
3271         (and:GPR (match_dup 1)
3272                  (match_dup 2)))
3273    (set (match_dup 3)
3274         (compare:CC (match_dup 0)
3275                     (const_int 0)))]
3276   ""
3277   [(set_attr "type" "logical")
3278    (set_attr "dot" "yes")
3279    (set_attr "length" "4,8")])
3281 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3282   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3283         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3284                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3285                     (const_int 0)))
3286    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3287         (and:GPR (match_dup 1)
3288                  (match_dup 2)))]
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<mode>3_imm_dot_shifted"
3308   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3309         (compare:CC
3310           (and:GPR
3311             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3312                           (match_operand:SI 4 "const_int_operand" "n"))
3313             (match_operand:GPR 2 "const_int_operand" "n"))
3314           (const_int 0)))
3315    (clobber (match_scratch:GPR 0 "=r"))]
3316   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3317                                    << INTVAL (operands[4])),
3318                           DImode)
3319    && (<MODE>mode == Pmode
3320        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3321    && rs6000_gen_cell_microcode"
3323   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3324   return "andi%e2. %0,%1,%u2";
3326   [(set_attr "type" "logical")
3327    (set_attr "dot" "yes")])
3330 (define_insn "and<mode>3_mask"
3331   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3332         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3333                  (match_operand:GPR 2 "const_int_operand" "n")))]
3334   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3336   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3338   [(set_attr "type" "shift")])
3340 (define_insn_and_split "*and<mode>3_mask_dot"
3341   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3342         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3343                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3344                     (const_int 0)))
3345    (clobber (match_scratch:GPR 0 "=r,r"))]
3346   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3347    && rs6000_gen_cell_microcode
3348    && !logical_const_operand (operands[2], <MODE>mode)
3349    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3351   if (which_alternative == 0)
3352     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3353   else
3354     return "#";
3356   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3357   [(set (match_dup 0)
3358         (and:GPR (match_dup 1)
3359                  (match_dup 2)))
3360    (set (match_dup 3)
3361         (compare:CC (match_dup 0)
3362                     (const_int 0)))]
3363   ""
3364   [(set_attr "type" "shift")
3365    (set_attr "dot" "yes")
3366    (set_attr "length" "4,8")])
3368 (define_insn_and_split "*and<mode>3_mask_dot2"
3369   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3370         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3371                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3372                     (const_int 0)))
3373    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3374         (and:GPR (match_dup 1)
3375                  (match_dup 2)))]
3376   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3377    && rs6000_gen_cell_microcode
3378    && !logical_const_operand (operands[2], <MODE>mode)
3379    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3381   if (which_alternative == 0)
3382     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3383   else
3384     return "#";
3386   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3387   [(set (match_dup 0)
3388         (and:GPR (match_dup 1)
3389                  (match_dup 2)))
3390    (set (match_dup 3)
3391         (compare:CC (match_dup 0)
3392                     (const_int 0)))]
3393   ""
3394   [(set_attr "type" "shift")
3395    (set_attr "dot" "yes")
3396    (set_attr "length" "4,8")])
3399 (define_insn_and_split "*and<mode>3_2insn"
3400   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3401         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3402                  (match_operand:GPR 2 "const_int_operand" "n")))]
3403   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3404    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3405         || (logical_const_operand (operands[2], <MODE>mode)
3406             && rs6000_gen_cell_microcode))"
3407   "#"
3408   "&& 1"
3409   [(pc)]
3411   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3412   DONE;
3414   [(set_attr "type" "shift")
3415    (set_attr "length" "8")])
3417 (define_insn_and_split "*and<mode>3_2insn_dot"
3418   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3419         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3420                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3421                     (const_int 0)))
3422    (clobber (match_scratch:GPR 0 "=r,r"))]
3423   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3424    && rs6000_gen_cell_microcode
3425    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3426    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3427         || (logical_const_operand (operands[2], <MODE>mode)
3428             && rs6000_gen_cell_microcode))"
3429   "#"
3430   "&& reload_completed"
3431   [(pc)]
3433   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3434   DONE;
3436   [(set_attr "type" "shift")
3437    (set_attr "dot" "yes")
3438    (set_attr "length" "8,12")])
3440 (define_insn_and_split "*and<mode>3_2insn_dot2"
3441   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3442         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3443                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3444                     (const_int 0)))
3445    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3446         (and:GPR (match_dup 1)
3447                  (match_dup 2)))]
3448   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3449    && rs6000_gen_cell_microcode
3450    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3451    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3452         || (logical_const_operand (operands[2], <MODE>mode)
3453             && rs6000_gen_cell_microcode))"
3454   "#"
3455   "&& reload_completed"
3456   [(pc)]
3458   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3459   DONE;
3461   [(set_attr "type" "shift")
3462    (set_attr "dot" "yes")
3463    (set_attr "length" "8,12")])
3466 (define_expand "<code><mode>3"
3467   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3468         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3469                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3470   ""
3472   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3473     {
3474       rs6000_split_logical (operands, <CODE>, false, false, false);
3475       DONE;
3476     }
3478   if (non_logical_cint_operand (operands[2], <MODE>mode))
3479     {
3480       rtx tmp = ((!can_create_pseudo_p ()
3481                   || rtx_equal_p (operands[0], operands[1]))
3482                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3484       HOST_WIDE_INT value = INTVAL (operands[2]);
3485       HOST_WIDE_INT lo = value & 0xffff;
3486       HOST_WIDE_INT hi = value - lo;
3488       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3489       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3490       DONE;
3491     }
3493   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3494     operands[2] = force_reg (<MODE>mode, operands[2]);
3497 (define_split
3498   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3499         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3500                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3501   ""
3502   [(set (match_dup 3)
3503         (iorxor:GPR (match_dup 1)
3504                     (match_dup 4)))
3505    (set (match_dup 0)
3506         (iorxor:GPR (match_dup 3)
3507                     (match_dup 5)))]
3509   operands[3] = ((!can_create_pseudo_p ()
3510                   || rtx_equal_p (operands[0], operands[1]))
3511                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3513   HOST_WIDE_INT value = INTVAL (operands[2]);
3514   HOST_WIDE_INT lo = value & 0xffff;
3515   HOST_WIDE_INT hi = value - lo;
3517   operands[4] = GEN_INT (hi);
3518   operands[5] = GEN_INT (lo);
3521 (define_insn "*bool<mode>3_imm"
3522   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3523         (match_operator:GPR 3 "boolean_or_operator"
3524          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3525           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3526   ""
3527   "%q3i%e2 %0,%1,%u2"
3528   [(set_attr "type" "logical")])
3530 (define_insn "*bool<mode>3"
3531   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3532         (match_operator:GPR 3 "boolean_operator"
3533          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3534           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3535   ""
3536   "%q3 %0,%1,%2"
3537   [(set_attr "type" "logical")])
3539 (define_insn_and_split "*bool<mode>3_dot"
3540   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3541         (compare:CC (match_operator:GPR 3 "boolean_operator"
3542          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3543           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3544          (const_int 0)))
3545    (clobber (match_scratch:GPR 0 "=r,r"))]
3546   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3547   "@
3548    %q3. %0,%1,%2
3549    #"
3550   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3551   [(set (match_dup 0)
3552         (match_dup 3))
3553    (set (match_dup 4)
3554         (compare:CC (match_dup 0)
3555                     (const_int 0)))]
3556   ""
3557   [(set_attr "type" "logical")
3558    (set_attr "dot" "yes")
3559    (set_attr "length" "4,8")])
3561 (define_insn_and_split "*bool<mode>3_dot2"
3562   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3563         (compare:CC (match_operator:GPR 3 "boolean_operator"
3564          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3565           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3566          (const_int 0)))
3567    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3568         (match_dup 3))]
3569   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3570   "@
3571    %q3. %0,%1,%2
3572    #"
3573   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3574   [(set (match_dup 0)
3575         (match_dup 3))
3576    (set (match_dup 4)
3577         (compare:CC (match_dup 0)
3578                     (const_int 0)))]
3579   ""
3580   [(set_attr "type" "logical")
3581    (set_attr "dot" "yes")
3582    (set_attr "length" "4,8")])
3585 (define_insn "*boolc<mode>3"
3586   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587         (match_operator:GPR 3 "boolean_operator"
3588          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3589           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3590   ""
3591   "%q3 %0,%1,%2"
3592   [(set_attr "type" "logical")])
3594 (define_insn_and_split "*boolc<mode>3_dot"
3595   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3596         (compare:CC (match_operator:GPR 3 "boolean_operator"
3597          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3598           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3599          (const_int 0)))
3600    (clobber (match_scratch:GPR 0 "=r,r"))]
3601   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3602   "@
3603    %q3. %0,%1,%2
3604    #"
3605   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3606   [(set (match_dup 0)
3607         (match_dup 3))
3608    (set (match_dup 4)
3609         (compare:CC (match_dup 0)
3610                     (const_int 0)))]
3611   ""
3612   [(set_attr "type" "logical")
3613    (set_attr "dot" "yes")
3614    (set_attr "length" "4,8")])
3616 (define_insn_and_split "*boolc<mode>3_dot2"
3617   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3618         (compare:CC (match_operator:GPR 3 "boolean_operator"
3619          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3620           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3621          (const_int 0)))
3622    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3623         (match_dup 3))]
3624   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3625   "@
3626    %q3. %0,%1,%2
3627    #"
3628   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3629   [(set (match_dup 0)
3630         (match_dup 3))
3631    (set (match_dup 4)
3632         (compare:CC (match_dup 0)
3633                     (const_int 0)))]
3634   ""
3635   [(set_attr "type" "logical")
3636    (set_attr "dot" "yes")
3637    (set_attr "length" "4,8")])
3640 (define_insn "*boolcc<mode>3"
3641   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3642         (match_operator:GPR 3 "boolean_operator"
3643          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3644           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3645   ""
3646   "%q3 %0,%1,%2"
3647   [(set_attr "type" "logical")])
3649 (define_insn_and_split "*boolcc<mode>3_dot"
3650   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3651         (compare:CC (match_operator:GPR 3 "boolean_operator"
3652          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3653           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3654          (const_int 0)))
3655    (clobber (match_scratch:GPR 0 "=r,r"))]
3656   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3657   "@
3658    %q3. %0,%1,%2
3659    #"
3660   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3661   [(set (match_dup 0)
3662         (match_dup 3))
3663    (set (match_dup 4)
3664         (compare:CC (match_dup 0)
3665                     (const_int 0)))]
3666   ""
3667   [(set_attr "type" "logical")
3668    (set_attr "dot" "yes")
3669    (set_attr "length" "4,8")])
3671 (define_insn_and_split "*boolcc<mode>3_dot2"
3672   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3673         (compare:CC (match_operator:GPR 3 "boolean_operator"
3674          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3675           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3676          (const_int 0)))
3677    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3678         (match_dup 3))]
3679   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3680   "@
3681    %q3. %0,%1,%2
3682    #"
3683   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3684   [(set (match_dup 0)
3685         (match_dup 3))
3686    (set (match_dup 4)
3687         (compare:CC (match_dup 0)
3688                     (const_int 0)))]
3689   ""
3690   [(set_attr "type" "logical")
3691    (set_attr "dot" "yes")
3692    (set_attr "length" "4,8")])
3695 ;; TODO: Should have dots of this as well.
3696 (define_insn "*eqv<mode>3"
3697   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3698         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3699                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3700   ""
3701   "eqv %0,%1,%2"
3702   [(set_attr "type" "logical")])
3704 ;; Rotate-and-mask and insert.
3706 (define_insn "*rotl<mode>3_mask"
3707   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3708         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3709                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3710                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3711                  (match_operand:GPR 3 "const_int_operand" "n")))]
3712   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3714   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3716   [(set_attr "type" "shift")
3717    (set_attr "maybe_var_shift" "yes")])
3719 (define_insn_and_split "*rotl<mode>3_mask_dot"
3720   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3721         (compare:CC
3722           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3723                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3724                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3725                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3726           (const_int 0)))
3727    (clobber (match_scratch:GPR 0 "=r,r"))]
3728   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3729    && rs6000_gen_cell_microcode
3730    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3732   if (which_alternative == 0)
3733     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3734   else
3735     return "#";
3737   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3738   [(set (match_dup 0)
3739         (and:GPR (match_dup 4)
3740                  (match_dup 3)))
3741    (set (match_dup 5)
3742         (compare:CC (match_dup 0)
3743                     (const_int 0)))]
3744   ""
3745   [(set_attr "type" "shift")
3746    (set_attr "maybe_var_shift" "yes")
3747    (set_attr "dot" "yes")
3748    (set_attr "length" "4,8")])
3750 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3751   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3752         (compare:CC
3753           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3754                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3755                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3756                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3757           (const_int 0)))
3758    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3759         (and:GPR (match_dup 4)
3760                  (match_dup 3)))]
3761   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3762    && rs6000_gen_cell_microcode
3763    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3765   if (which_alternative == 0)
3766     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3767   else
3768     return "#";
3770   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3771   [(set (match_dup 0)
3772         (and:GPR (match_dup 4)
3773                  (match_dup 3)))
3774    (set (match_dup 5)
3775         (compare:CC (match_dup 0)
3776                     (const_int 0)))]
3777   ""
3778   [(set_attr "type" "shift")
3779    (set_attr "maybe_var_shift" "yes")
3780    (set_attr "dot" "yes")
3781    (set_attr "length" "4,8")])
3783 ; Special case for less-than-0.  We can do it with just one machine
3784 ; instruction, but the generic optimizers do not realise it is cheap.
3785 (define_insn "*lt0_disi"
3786   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3787         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3788                (const_int 0)))]
3789   "TARGET_POWERPC64"
3790   "rlwinm %0,%1,1,31,31"
3791   [(set_attr "type" "shift")])
3795 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3796 ; both are an AND so are the same precedence).
3797 (define_insn "*rotl<mode>3_insert"
3798   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3799         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3800                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3801                             (match_operand:SI 2 "const_int_operand" "n")])
3802                           (match_operand:GPR 3 "const_int_operand" "n"))
3803                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3804                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3805   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3806    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3808   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3810   [(set_attr "type" "insert")])
3811 ; FIXME: this needs an attr "size", so that the scheduler can see the
3812 ; difference between rlwimi and rldimi.  We also might want dot forms,
3813 ; but not for rlwimi on POWER4 and similar processors.
3815 (define_insn "*rotl<mode>3_insert_2"
3816   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3817         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3818                           (match_operand:GPR 6 "const_int_operand" "n"))
3819                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3820                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3821                             (match_operand:SI 2 "const_int_operand" "n")])
3822                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3823   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3824    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3826   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3828   [(set_attr "type" "insert")])
3830 ; There are also some forms without one of the ANDs.
3831 (define_insn "*rotl<mode>3_insert_3"
3832   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3833         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3834                           (match_operand:GPR 4 "const_int_operand" "n"))
3835                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3836                              (match_operand:SI 2 "const_int_operand" "n"))))]
3837   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3839   if (<MODE>mode == SImode)
3840     return "rlwimi %0,%1,%h2,0,31-%h2";
3841   else
3842     return "rldimi %0,%1,%H2,0";
3844   [(set_attr "type" "insert")])
3846 (define_insn "*rotl<mode>3_insert_4"
3847   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3848         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3849                           (match_operand:GPR 4 "const_int_operand" "n"))
3850                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3851                                (match_operand:SI 2 "const_int_operand" "n"))))]
3852   "<MODE>mode == SImode &&
3853    GET_MODE_PRECISION (<MODE>mode)
3854    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3856   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3857                          - INTVAL (operands[2]));
3858   if (<MODE>mode == SImode)
3859     return "rlwimi %0,%1,%h2,32-%h2,31";
3860   else
3861     return "rldimi %0,%1,%H2,64-%H2";
3863   [(set_attr "type" "insert")])
3865 (define_insn "*rotlsi3_insert_5"
3866   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3867         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3868                         (match_operand:SI 2 "const_int_operand" "n,n"))
3869                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3870                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3871   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3872    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3873    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3874   "@
3875    rlwimi %0,%3,0,%4
3876    rlwimi %0,%1,0,%2"
3877   [(set_attr "type" "insert")])
3879 (define_insn "*rotldi3_insert_6"
3880   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3881         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3882                         (match_operand:DI 2 "const_int_operand" "n"))
3883                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3884                         (match_operand:DI 4 "const_int_operand" "n"))))]
3885   "exact_log2 (-UINTVAL (operands[2])) > 0
3886    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3888   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3889   return "rldimi %0,%3,0,%5";
3891   [(set_attr "type" "insert")
3892    (set_attr "size" "64")])
3894 (define_insn "*rotldi3_insert_7"
3895   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3896         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3897                         (match_operand:DI 4 "const_int_operand" "n"))
3898                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3899                         (match_operand:DI 2 "const_int_operand" "n"))))]
3900   "exact_log2 (-UINTVAL (operands[2])) > 0
3901    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3903   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3904   return "rldimi %0,%3,0,%5";
3906   [(set_attr "type" "insert")
3907    (set_attr "size" "64")])
3910 ; This handles the important case of multiple-precision shifts.  There is
3911 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3912 (define_split
3913   [(set (match_operand:GPR 0 "gpc_reg_operand")
3914         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3915                              (match_operand:SI 3 "const_int_operand"))
3916                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3917                                (match_operand:SI 4 "const_int_operand"))))]
3918   "can_create_pseudo_p ()
3919    && INTVAL (operands[3]) + INTVAL (operands[4])
3920       >= GET_MODE_PRECISION (<MODE>mode)"
3921   [(set (match_dup 5)
3922         (lshiftrt:GPR (match_dup 2)
3923                       (match_dup 4)))
3924    (set (match_dup 0)
3925         (ior:GPR (and:GPR (match_dup 5)
3926                           (match_dup 6))
3927                  (ashift:GPR (match_dup 1)
3928                              (match_dup 3))))]
3930   unsigned HOST_WIDE_INT mask = 1;
3931   mask = (mask << INTVAL (operands[3])) - 1;
3932   operands[5] = gen_reg_rtx (<MODE>mode);
3933   operands[6] = GEN_INT (mask);
3936 (define_split
3937   [(set (match_operand:GPR 0 "gpc_reg_operand")
3938         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3939                                (match_operand:SI 4 "const_int_operand"))
3940                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3941                              (match_operand:SI 3 "const_int_operand"))))]
3942   "can_create_pseudo_p ()
3943    && INTVAL (operands[3]) + INTVAL (operands[4])
3944       >= GET_MODE_PRECISION (<MODE>mode)"
3945   [(set (match_dup 5)
3946         (lshiftrt:GPR (match_dup 2)
3947                       (match_dup 4)))
3948    (set (match_dup 0)
3949         (ior:GPR (and:GPR (match_dup 5)
3950                           (match_dup 6))
3951                  (ashift:GPR (match_dup 1)
3952                              (match_dup 3))))]
3954   unsigned HOST_WIDE_INT mask = 1;
3955   mask = (mask << INTVAL (operands[3])) - 1;
3956   operands[5] = gen_reg_rtx (<MODE>mode);
3957   operands[6] = GEN_INT (mask);
3961 ; Another important case is setting some bits to 1; we can do that with
3962 ; an insert instruction, in many cases.
3963 (define_insn_and_split "*ior<mode>_mask"
3964   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3965         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3966                  (match_operand:GPR 2 "const_int_operand" "n")))
3967    (clobber (match_scratch:GPR 3 "=r"))]
3968   "!logical_const_operand (operands[2], <MODE>mode)
3969    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3970   "#"
3971   "&& 1"
3972   [(set (match_dup 3)
3973         (const_int -1))
3974    (set (match_dup 0)
3975         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3976                                       (match_dup 4))
3977                           (match_dup 2))
3978                  (and:GPR (match_dup 1)
3979                           (match_dup 5))))]
3981   int nb, ne;
3982   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3983   if (GET_CODE (operands[3]) == SCRATCH)
3984     operands[3] = gen_reg_rtx (<MODE>mode);
3985   operands[4] = GEN_INT (ne);
3986   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3988   [(set_attr "type" "two")
3989    (set_attr "length" "8")])
3992 ;; Now the simple shifts.
3994 (define_insn "rotl<mode>3"
3995   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3996         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3997                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3998   ""
3999   "rotl<wd>%I2 %0,%1,%<hH>2"
4000   [(set_attr "type" "shift")
4001    (set_attr "maybe_var_shift" "yes")])
4003 (define_insn "*rotlsi3_64"
4004   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4005         (zero_extend:DI
4006             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4007                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4008   "TARGET_POWERPC64"
4009   "rotlw%I2 %0,%1,%h2"
4010   [(set_attr "type" "shift")
4011    (set_attr "maybe_var_shift" "yes")])
4013 (define_insn_and_split "*rotl<mode>3_dot"
4014   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4015         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4016                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4017                     (const_int 0)))
4018    (clobber (match_scratch:GPR 0 "=r,r"))]
4019   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4020   "@
4021    rotl<wd>%I2. %0,%1,%<hH>2
4022    #"
4023   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4024   [(set (match_dup 0)
4025         (rotate:GPR (match_dup 1)
4026                     (match_dup 2)))
4027    (set (match_dup 3)
4028         (compare:CC (match_dup 0)
4029                     (const_int 0)))]
4030   ""
4031   [(set_attr "type" "shift")
4032    (set_attr "maybe_var_shift" "yes")
4033    (set_attr "dot" "yes")
4034    (set_attr "length" "4,8")])
4036 (define_insn_and_split "*rotl<mode>3_dot2"
4037   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4038         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4039                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4040                     (const_int 0)))
4041    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4042         (rotate:GPR (match_dup 1)
4043                     (match_dup 2)))]
4044   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4045   "@
4046    rotl<wd>%I2. %0,%1,%<hH>2
4047    #"
4048   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4049   [(set (match_dup 0)
4050         (rotate:GPR (match_dup 1)
4051                     (match_dup 2)))
4052    (set (match_dup 3)
4053         (compare:CC (match_dup 0)
4054                     (const_int 0)))]
4055   ""
4056   [(set_attr "type" "shift")
4057    (set_attr "maybe_var_shift" "yes")
4058    (set_attr "dot" "yes")
4059    (set_attr "length" "4,8")])
4062 (define_insn "ashl<mode>3"
4063   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4064         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4065                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4066   ""
4067   "sl<wd>%I2 %0,%1,%<hH>2"
4068   [(set_attr "type" "shift")
4069    (set_attr "maybe_var_shift" "yes")])
4071 (define_insn "*ashlsi3_64"
4072   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4073         (zero_extend:DI
4074             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4075                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4076   "TARGET_POWERPC64"
4077   "slw%I2 %0,%1,%h2"
4078   [(set_attr "type" "shift")
4079    (set_attr "maybe_var_shift" "yes")])
4081 (define_insn_and_split "*ashl<mode>3_dot"
4082   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4083         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4084                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4085                     (const_int 0)))
4086    (clobber (match_scratch:GPR 0 "=r,r"))]
4087   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4088   "@
4089    sl<wd>%I2. %0,%1,%<hH>2
4090    #"
4091   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4092   [(set (match_dup 0)
4093         (ashift:GPR (match_dup 1)
4094                     (match_dup 2)))
4095    (set (match_dup 3)
4096         (compare:CC (match_dup 0)
4097                     (const_int 0)))]
4098   ""
4099   [(set_attr "type" "shift")
4100    (set_attr "maybe_var_shift" "yes")
4101    (set_attr "dot" "yes")
4102    (set_attr "length" "4,8")])
4104 (define_insn_and_split "*ashl<mode>3_dot2"
4105   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4106         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4107                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4108                     (const_int 0)))
4109    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4110         (ashift:GPR (match_dup 1)
4111                     (match_dup 2)))]
4112   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4113   "@
4114    sl<wd>%I2. %0,%1,%<hH>2
4115    #"
4116   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4117   [(set (match_dup 0)
4118         (ashift:GPR (match_dup 1)
4119                     (match_dup 2)))
4120    (set (match_dup 3)
4121         (compare:CC (match_dup 0)
4122                     (const_int 0)))]
4123   ""
4124   [(set_attr "type" "shift")
4125    (set_attr "maybe_var_shift" "yes")
4126    (set_attr "dot" "yes")
4127    (set_attr "length" "4,8")])
4129 ;; Pretend we have a memory form of extswsli until register allocation is done
4130 ;; so that we use LWZ to load the value from memory, instead of LWA.
4131 (define_insn_and_split "ashdi3_extswsli"
4132   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4133         (ashift:DI
4134          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4135          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4136   "TARGET_EXTSWSLI"
4137   "@
4138    extswsli %0,%1,%2
4139    #"
4140   "&& reload_completed && MEM_P (operands[1])"
4141   [(set (match_dup 3)
4142         (match_dup 1))
4143    (set (match_dup 0)
4144         (ashift:DI (sign_extend:DI (match_dup 3))
4145                    (match_dup 2)))]
4147   operands[3] = gen_lowpart (SImode, operands[0]);
4149   [(set_attr "type" "shift")
4150    (set_attr "maybe_var_shift" "no")])
4153 (define_insn_and_split "ashdi3_extswsli_dot"
4154   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4155         (compare:CC
4156          (ashift:DI
4157           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4158           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4159          (const_int 0)))
4160    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4161   "TARGET_EXTSWSLI"
4162   "@
4163    extswsli. %0,%1,%2
4164    #
4165    #
4166    #"
4167   "&& reload_completed
4168    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4169        || memory_operand (operands[1], SImode))"
4170   [(pc)]
4172   rtx dest = operands[0];
4173   rtx src = operands[1];
4174   rtx shift = operands[2];
4175   rtx cr = operands[3];
4176   rtx src2;
4178   if (!MEM_P (src))
4179     src2 = src;
4180   else
4181     {
4182       src2 = gen_lowpart (SImode, dest);
4183       emit_move_insn (src2, src);
4184     }
4186   if (REGNO (cr) == CR0_REGNO)
4187     {
4188       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4189       DONE;
4190     }
4192   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4193   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4194   DONE;
4196   [(set_attr "type" "shift")
4197    (set_attr "maybe_var_shift" "no")
4198    (set_attr "dot" "yes")
4199    (set_attr "length" "4,8,8,12")])
4201 (define_insn_and_split "ashdi3_extswsli_dot2"
4202   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4203         (compare:CC
4204          (ashift:DI
4205           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4206           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4207          (const_int 0)))
4208    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4209         (ashift:DI (sign_extend:DI (match_dup 1))
4210                    (match_dup 2)))]
4211   "TARGET_EXTSWSLI"
4212   "@
4213    extswsli. %0,%1,%2
4214    #
4215    #
4216    #"
4217   "&& reload_completed
4218    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4219        || memory_operand (operands[1], SImode))"
4220   [(pc)]
4222   rtx dest = operands[0];
4223   rtx src = operands[1];
4224   rtx shift = operands[2];
4225   rtx cr = operands[3];
4226   rtx src2;
4228   if (!MEM_P (src))
4229     src2 = src;
4230   else
4231     {
4232       src2 = gen_lowpart (SImode, dest);
4233       emit_move_insn (src2, src);
4234     }
4236   if (REGNO (cr) == CR0_REGNO)
4237     {
4238       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4239       DONE;
4240     }
4242   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4243   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4244   DONE;
4246   [(set_attr "type" "shift")
4247    (set_attr "maybe_var_shift" "no")
4248    (set_attr "dot" "yes")
4249    (set_attr "length" "4,8,8,12")])
4251 (define_insn "lshr<mode>3"
4252   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4253         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4254                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4255   ""
4256   "sr<wd>%I2 %0,%1,%<hH>2"
4257   [(set_attr "type" "shift")
4258    (set_attr "maybe_var_shift" "yes")])
4260 (define_insn "*lshrsi3_64"
4261   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4262         (zero_extend:DI
4263             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4264                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4265   "TARGET_POWERPC64"
4266   "srw%I2 %0,%1,%h2"
4267   [(set_attr "type" "shift")
4268    (set_attr "maybe_var_shift" "yes")])
4270 (define_insn_and_split "*lshr<mode>3_dot"
4271   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4272         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4273                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4274                     (const_int 0)))
4275    (clobber (match_scratch:GPR 0 "=r,r"))]
4276   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4277   "@
4278    sr<wd>%I2. %0,%1,%<hH>2
4279    #"
4280   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4281   [(set (match_dup 0)
4282         (lshiftrt:GPR (match_dup 1)
4283                       (match_dup 2)))
4284    (set (match_dup 3)
4285         (compare:CC (match_dup 0)
4286                     (const_int 0)))]
4287   ""
4288   [(set_attr "type" "shift")
4289    (set_attr "maybe_var_shift" "yes")
4290    (set_attr "dot" "yes")
4291    (set_attr "length" "4,8")])
4293 (define_insn_and_split "*lshr<mode>3_dot2"
4294   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4295         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4296                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4297                     (const_int 0)))
4298    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4299         (lshiftrt:GPR (match_dup 1)
4300                       (match_dup 2)))]
4301   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4302   "@
4303    sr<wd>%I2. %0,%1,%<hH>2
4304    #"
4305   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4306   [(set (match_dup 0)
4307         (lshiftrt:GPR (match_dup 1)
4308                       (match_dup 2)))
4309    (set (match_dup 3)
4310         (compare:CC (match_dup 0)
4311                     (const_int 0)))]
4312   ""
4313   [(set_attr "type" "shift")
4314    (set_attr "maybe_var_shift" "yes")
4315    (set_attr "dot" "yes")
4316    (set_attr "length" "4,8")])
4319 (define_insn "ashr<mode>3"
4320   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4321         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4322                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4323    (clobber (reg:GPR CA_REGNO))]
4324   ""
4325   "sra<wd>%I2 %0,%1,%<hH>2"
4326   [(set_attr "type" "shift")
4327    (set_attr "maybe_var_shift" "yes")])
4329 (define_insn "*ashrsi3_64"
4330   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4331         (sign_extend:DI
4332             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4333                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4334    (clobber (reg:SI CA_REGNO))]
4335   "TARGET_POWERPC64"
4336   "sraw%I2 %0,%1,%h2"
4337   [(set_attr "type" "shift")
4338    (set_attr "maybe_var_shift" "yes")])
4340 (define_insn_and_split "*ashr<mode>3_dot"
4341   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4342         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4343                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4344                     (const_int 0)))
4345    (clobber (match_scratch:GPR 0 "=r,r"))
4346    (clobber (reg:GPR CA_REGNO))]
4347   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4348   "@
4349    sra<wd>%I2. %0,%1,%<hH>2
4350    #"
4351   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4352   [(parallel [(set (match_dup 0)
4353                    (ashiftrt:GPR (match_dup 1)
4354                                  (match_dup 2)))
4355               (clobber (reg:GPR CA_REGNO))])
4356    (set (match_dup 3)
4357         (compare:CC (match_dup 0)
4358                     (const_int 0)))]
4359   ""
4360   [(set_attr "type" "shift")
4361    (set_attr "maybe_var_shift" "yes")
4362    (set_attr "dot" "yes")
4363    (set_attr "length" "4,8")])
4365 (define_insn_and_split "*ashr<mode>3_dot2"
4366   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4367         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4368                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4369                     (const_int 0)))
4370    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4371         (ashiftrt:GPR (match_dup 1)
4372                       (match_dup 2)))
4373    (clobber (reg:GPR CA_REGNO))]
4374   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4375   "@
4376    sra<wd>%I2. %0,%1,%<hH>2
4377    #"
4378   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4379   [(parallel [(set (match_dup 0)
4380                    (ashiftrt:GPR (match_dup 1)
4381                                  (match_dup 2)))
4382               (clobber (reg:GPR CA_REGNO))])
4383    (set (match_dup 3)
4384         (compare:CC (match_dup 0)
4385                     (const_int 0)))]
4386   ""
4387   [(set_attr "type" "shift")
4388    (set_attr "maybe_var_shift" "yes")
4389    (set_attr "dot" "yes")
4390    (set_attr "length" "4,8")])
4392 ;; Builtins to replace a division to generate FRE reciprocal estimate
4393 ;; instructions and the necessary fixup instructions
4394 (define_expand "recip<mode>3"
4395   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4396    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4397    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4398   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4400    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4401    DONE;
4404 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4405 ;; hardware division.  This is only done before register allocation and with
4406 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4407 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4408 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4409 (define_split
4410   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4411         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4412                     (match_operand 2 "gpc_reg_operand" "")))]
4413   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4414    && can_create_pseudo_p () && flag_finite_math_only
4415    && !flag_trapping_math && flag_reciprocal_math"
4416   [(const_int 0)]
4418   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4419   DONE;
4422 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4423 ;; appropriate fixup.
4424 (define_expand "rsqrt<mode>2"
4425   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4426    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4427   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4429   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4430   DONE;
4433 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4434 ;; modes here, and also add in conditional vsx/power8-vector support to access
4435 ;; values in the traditional Altivec registers if the appropriate
4436 ;; -mupper-regs-{df,sf} option is enabled.
4438 (define_expand "abs<mode>2"
4439   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4440         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4441   "TARGET_<MODE>_INSN"
4442   "")
4444 (define_insn "*abs<mode>2_fpr"
4445   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4446         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4447   "TARGET_<MODE>_FPR"
4448   "@
4449    fabs %0,%1
4450    xsabsdp %x0,%x1"
4451   [(set_attr "type" "fpsimple")
4452    (set_attr "fp_type" "fp_addsub_<Fs>")])
4454 (define_insn "*nabs<mode>2_fpr"
4455   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4456         (neg:SFDF
4457          (abs:SFDF
4458           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4459   "TARGET_<MODE>_FPR"
4460   "@
4461    fnabs %0,%1
4462    xsnabsdp %x0,%x1"
4463   [(set_attr "type" "fpsimple")
4464    (set_attr "fp_type" "fp_addsub_<Fs>")])
4466 (define_expand "neg<mode>2"
4467   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4468         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4469   "TARGET_<MODE>_INSN"
4470   "")
4472 (define_insn "*neg<mode>2_fpr"
4473   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4474         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4475   "TARGET_<MODE>_FPR"
4476   "@
4477    fneg %0,%1
4478    xsnegdp %x0,%x1"
4479   [(set_attr "type" "fpsimple")
4480    (set_attr "fp_type" "fp_addsub_<Fs>")])
4482 (define_expand "add<mode>3"
4483   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4484         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4485                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4486   "TARGET_<MODE>_INSN"
4487   "")
4489 (define_insn "*add<mode>3_fpr"
4490   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4491         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4492                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4493   "TARGET_<MODE>_FPR"
4494   "@
4495    fadd<Ftrad> %0,%1,%2
4496    xsadd<Fvsx> %x0,%x1,%x2"
4497   [(set_attr "type" "fp")
4498    (set_attr "fp_type" "fp_addsub_<Fs>")])
4500 (define_expand "sub<mode>3"
4501   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4502         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4503                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4504   "TARGET_<MODE>_INSN"
4505   "")
4507 (define_insn "*sub<mode>3_fpr"
4508   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4509         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4510                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4511   "TARGET_<MODE>_FPR"
4512   "@
4513    fsub<Ftrad> %0,%1,%2
4514    xssub<Fvsx> %x0,%x1,%x2"
4515   [(set_attr "type" "fp")
4516    (set_attr "fp_type" "fp_addsub_<Fs>")])
4518 (define_expand "mul<mode>3"
4519   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4520         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4521                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4522   "TARGET_<MODE>_INSN"
4523   "")
4525 (define_insn "*mul<mode>3_fpr"
4526   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4527         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4528                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4529   "TARGET_<MODE>_FPR"
4530   "@
4531    fmul<Ftrad> %0,%1,%2
4532    xsmul<Fvsx> %x0,%x1,%x2"
4533   [(set_attr "type" "dmul")
4534    (set_attr "fp_type" "fp_mul_<Fs>")])
4536 (define_expand "div<mode>3"
4537   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4538         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4539                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4540   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4542   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4543       && can_create_pseudo_p () && flag_finite_math_only
4544       && !flag_trapping_math && flag_reciprocal_math)
4545     {
4546       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4547       DONE;
4548     }
4551 (define_insn "*div<mode>3_fpr"
4552   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4553         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4554                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4555   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4556   "@
4557    fdiv<Ftrad> %0,%1,%2
4558    xsdiv<Fvsx> %x0,%x1,%x2"
4559   [(set_attr "type" "<Fs>div")
4560    (set_attr "fp_type" "fp_div_<Fs>")])
4562 (define_insn "*sqrt<mode>2_internal"
4563   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4564         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4565   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4566    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4567   "@
4568    fsqrt<Ftrad> %0,%1
4569    xssqrt<Fvsx> %x0,%x1"
4570   [(set_attr "type" "<Fs>sqrt")
4571    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4573 (define_expand "sqrt<mode>2"
4574   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4575         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4576   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4577    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4579   if (<MODE>mode == SFmode
4580       && TARGET_RECIP_PRECISION
4581       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4582       && !optimize_function_for_size_p (cfun)
4583       && flag_finite_math_only && !flag_trapping_math
4584       && flag_unsafe_math_optimizations)
4585     {
4586       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4587       DONE;
4588     }
4591 ;; Floating point reciprocal approximation
4592 (define_insn "fre<Fs>"
4593   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4594         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4595                      UNSPEC_FRES))]
4596   "TARGET_<FFRE>"
4597   "@
4598    fre<Ftrad> %0,%1
4599    xsre<Fvsx> %x0,%x1"
4600   [(set_attr "type" "fp")])
4602 (define_insn "*rsqrt<mode>2"
4603   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4604         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4605                      UNSPEC_RSQRT))]
4606   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4607   "@
4608    frsqrte<Ftrad> %0,%1
4609    xsrsqrte<Fvsx> %x0,%x1"
4610   [(set_attr "type" "fp")])
4612 ;; Floating point comparisons
4613 (define_insn "*cmp<mode>_fpr"
4614   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4615         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4616                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4617   "TARGET_<MODE>_FPR"
4618   "@
4619    fcmpu %0,%1,%2
4620    xscmpudp %0,%x1,%x2"
4621   [(set_attr "type" "fpcompare")])
4623 ;; Floating point conversions
4624 (define_expand "extendsfdf2"
4625   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4626         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4627   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4628   "")
4630 (define_insn_and_split "*extendsfdf2_fpr"
4631   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4632         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4633   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4634   "@
4635    #
4636    fmr %0,%1
4637    lfs%U1%X1 %0,%1
4638    #
4639    xscpsgndp %x0,%x1,%x1
4640    lxsspx %x0,%y1
4641    lxssp %0,%1"
4642   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4643   [(const_int 0)]
4645   emit_note (NOTE_INSN_DELETED);
4646   DONE;
4648   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4650 (define_expand "truncdfsf2"
4651   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4652         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4653   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4654   "")
4656 (define_insn "*truncdfsf2_fpr"
4657   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4658         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4659   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4660   "@
4661    frsp %0,%1
4662    xsrsp %x0,%x1"
4663   [(set_attr "type" "fp")])
4665 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4666 ;; builtins.c and optabs.c that are not correct for IBM long double
4667 ;; when little-endian.
4668 (define_expand "signbit<mode>2"
4669   [(set (match_dup 2)
4670         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4671    (set (match_dup 3)
4672         (subreg:DI (match_dup 2) 0))
4673    (set (match_dup 4)
4674         (match_dup 5))
4675    (set (match_operand:SI 0 "gpc_reg_operand" "")
4676         (match_dup 6))]
4677   "TARGET_HARD_FLOAT
4678    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4679    && (!FLOAT128_IEEE_P (<MODE>mode)
4680        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4682   if (FLOAT128_IEEE_P (<MODE>mode))
4683     {
4684       if (<MODE>mode == KFmode)
4685         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4686       else if (<MODE>mode == TFmode)
4687         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4688       else
4689         gcc_unreachable ();
4690       DONE;
4691     }
4692   operands[2] = gen_reg_rtx (DFmode);
4693   operands[3] = gen_reg_rtx (DImode);
4694   if (TARGET_POWERPC64)
4695     {
4696       operands[4] = gen_reg_rtx (DImode);
4697       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4698       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4699                                     WORDS_BIG_ENDIAN ? 4 : 0);
4700     }
4701   else
4702     {
4703       operands[4] = gen_reg_rtx (SImode);
4704       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4705                                     WORDS_BIG_ENDIAN ? 0 : 4);
4706       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4707     }
4710 (define_expand "copysign<mode>3"
4711   [(set (match_dup 3)
4712         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4713    (set (match_dup 4)
4714         (neg:SFDF (abs:SFDF (match_dup 1))))
4715    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4716         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4717                                (match_dup 5))
4718                          (match_dup 3)
4719                          (match_dup 4)))]
4720   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4721    && ((TARGET_PPC_GFXOPT
4722         && !HONOR_NANS (<MODE>mode)
4723         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4724        || TARGET_CMPB
4725        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4727   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4728     {
4729       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4730                                              operands[2]));
4731       DONE;
4732     }
4734    operands[3] = gen_reg_rtx (<MODE>mode);
4735    operands[4] = gen_reg_rtx (<MODE>mode);
4736    operands[5] = CONST0_RTX (<MODE>mode);
4737   })
4739 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4740 ;; and load.
4741 (define_insn_and_split "signbit<mode>2_dm"
4742   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4743         (unspec:SI
4744          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4745          UNSPEC_SIGNBIT))]
4746   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4747   "#"
4748   "&& reload_completed"
4749   [(const_int 0)]
4751   rs6000_split_signbit (operands[0], operands[1]);
4752   DONE;
4754  [(set_attr "length" "8,8,4")
4755   (set_attr "type" "mftgpr,load,integer")])
4757 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4758   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4759         (any_extend:DI
4760          (unspec:SI
4761           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4762           UNSPEC_SIGNBIT)))]
4763   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4764   "#"
4765   "&& reload_completed"
4766   [(const_int 0)]
4768   rs6000_split_signbit (operands[0], operands[1]);
4769   DONE;
4771  [(set_attr "length" "8,8,4")
4772   (set_attr "type" "mftgpr,load,integer")])
4774 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4775 ;; point types, which makes normal SUBREG's problematical. Instead use a
4776 ;; special pattern to avoid using a normal movdi.
4777 (define_insn "signbit<mode>2_dm2"
4778   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4779         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4780                     (const_int 0)]
4781                    UNSPEC_SIGNBIT))]
4782   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4783   "mfvsrd %0,%x1"
4784  [(set_attr "type" "mftgpr")])
4787 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4788 ;; compiler from optimizing -0.0
4789 (define_insn "copysign<mode>3_fcpsgn"
4790   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4791         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4792                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4793                      UNSPEC_COPYSIGN))]
4794   "TARGET_<MODE>_FPR && TARGET_CMPB"
4795   "@
4796    fcpsgn %0,%2,%1
4797    xscpsgndp %x0,%x2,%x1"
4798   [(set_attr "type" "fpsimple")])
4800 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4801 ;; fsel instruction and some auxiliary computations.  Then we just have a
4802 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4803 ;; combine.
4804 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4805 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4806 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4807 ;; define_splits to make them if made by combine.  On VSX machines we have the
4808 ;; min/max instructions.
4810 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4811 ;; to allow either DF/SF to use only traditional registers.
4813 (define_expand "s<minmax><mode>3"
4814   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4815         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4816                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4817   "TARGET_MINMAX_<MODE>"
4819   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4820   DONE;
4823 (define_insn "*s<minmax><mode>3_vsx"
4824   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4825         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4826                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4827   "TARGET_VSX && TARGET_<MODE>_FPR"
4829   return (TARGET_P9_MINMAX
4830           ? "xs<minmax>cdp %x0,%x1,%x2"
4831           : "xs<minmax>dp %x0,%x1,%x2");
4833   [(set_attr "type" "fp")])
4835 ;; The conditional move instructions allow us to perform max and min operations
4836 ;; even when we don't have the appropriate max/min instruction using the FSEL
4837 ;; instruction.
4839 (define_insn_and_split "*s<minmax><mode>3_fpr"
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_VSX && TARGET_MINMAX_<MODE>"
4844   "#"
4845   "&& 1"
4846   [(const_int 0)]
4848   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4849   DONE;
4852 (define_expand "mov<mode>cc"
4853    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4854          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4855                            (match_operand:GPR 2 "gpc_reg_operand" "")
4856                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4857   "TARGET_ISEL<sel>"
4858   "
4860   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4861     DONE;
4862   else
4863     FAIL;
4866 ;; We use the BASE_REGS for the isel input operands because, if rA is
4867 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4868 ;; because we may switch the operands and rB may end up being rA.
4870 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4871 ;; leave out the mode in operand 4 and use one pattern, but reload can
4872 ;; change the mode underneath our feet and then gets confused trying
4873 ;; to reload the value.
4874 (define_insn "isel_signed_<mode>"
4875   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4876         (if_then_else:GPR
4877          (match_operator 1 "scc_comparison_operator"
4878                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4879                           (const_int 0)])
4880          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4881          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4882   "TARGET_ISEL<sel>"
4883   "*
4884 { return output_isel (operands); }"
4885   [(set_attr "type" "isel")
4886    (set_attr "length" "4")])
4888 (define_insn "isel_unsigned_<mode>"
4889   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4890         (if_then_else:GPR
4891          (match_operator 1 "scc_comparison_operator"
4892                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4893                           (const_int 0)])
4894          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4895          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4896   "TARGET_ISEL<sel>"
4897   "*
4898 { return output_isel (operands); }"
4899   [(set_attr "type" "isel")
4900    (set_attr "length" "4")])
4902 ;; These patterns can be useful for combine; they let combine know that
4903 ;; isel can handle reversed comparisons so long as the operands are
4904 ;; registers.
4906 (define_insn "*isel_reversed_signed_<mode>"
4907   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4908         (if_then_else:GPR
4909          (match_operator 1 "scc_rev_comparison_operator"
4910                          [(match_operand:CC 4 "cc_reg_operand" "y")
4911                           (const_int 0)])
4912          (match_operand:GPR 2 "gpc_reg_operand" "b")
4913          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4914   "TARGET_ISEL<sel>"
4915   "*
4916 { return output_isel (operands); }"
4917   [(set_attr "type" "isel")
4918    (set_attr "length" "4")])
4920 (define_insn "*isel_reversed_unsigned_<mode>"
4921   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4922         (if_then_else:GPR
4923          (match_operator 1 "scc_rev_comparison_operator"
4924                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4925                           (const_int 0)])
4926          (match_operand:GPR 2 "gpc_reg_operand" "b")
4927          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4928   "TARGET_ISEL<sel>"
4929   "*
4930 { return output_isel (operands); }"
4931   [(set_attr "type" "isel")
4932    (set_attr "length" "4")])
4934 ;; Floating point conditional move
4935 (define_expand "mov<mode>cc"
4936    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4937          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4938                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4939                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4940   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4941   "
4943   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4944     DONE;
4945   else
4946     FAIL;
4949 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4950   [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4951         (if_then_else:SFDF
4952          (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4953              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4954          (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4955          (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4956   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4957   "fsel %0,%1,%2,%3"
4958   [(set_attr "type" "fp")])
4960 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4961   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4962         (if_then_else:SFDF
4963          (match_operator:CCFP 1 "fpmask_comparison_operator"
4964                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4965                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4966          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4967          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4968    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4969   "TARGET_P9_MINMAX"
4970   "#"
4971   ""
4972   [(set (match_dup 6)
4973         (if_then_else:V2DI (match_dup 1)
4974                            (match_dup 7)
4975                            (match_dup 8)))
4976    (set (match_dup 0)
4977         (if_then_else:SFDF (ne (match_dup 6)
4978                                (match_dup 8))
4979                            (match_dup 4)
4980                            (match_dup 5)))]
4982   if (GET_CODE (operands[6]) == SCRATCH)
4983     operands[6] = gen_reg_rtx (V2DImode);
4985   operands[7] = CONSTM1_RTX (V2DImode);
4986   operands[8] = CONST0_RTX (V2DImode);
4988  [(set_attr "length" "8")
4989   (set_attr "type" "vecperm")])
4991 ;; Handle inverting the fpmask comparisons.
4992 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4993   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4994         (if_then_else:SFDF
4995          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4996                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4997                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4998          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4999          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5000    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5001   "TARGET_P9_MINMAX"
5002   "#"
5003   "&& 1"
5004   [(set (match_dup 6)
5005         (if_then_else:V2DI (match_dup 9)
5006                            (match_dup 7)
5007                            (match_dup 8)))
5008    (set (match_dup 0)
5009         (if_then_else:SFDF (ne (match_dup 6)
5010                                (match_dup 8))
5011                            (match_dup 5)
5012                            (match_dup 4)))]
5014   rtx op1 = operands[1];
5015   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5017   if (GET_CODE (operands[6]) == SCRATCH)
5018     operands[6] = gen_reg_rtx (V2DImode);
5020   operands[7] = CONSTM1_RTX (V2DImode);
5021   operands[8] = CONST0_RTX (V2DImode);
5023   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5025  [(set_attr "length" "8")
5026   (set_attr "type" "vecperm")])
5028 (define_insn "*fpmask<mode>"
5029   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5030         (if_then_else:V2DI
5031          (match_operator:CCFP 1 "fpmask_comparison_operator"
5032                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5033                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5034          (match_operand:V2DI 4 "all_ones_constant" "")
5035          (match_operand:V2DI 5 "zero_constant" "")))]
5036   "TARGET_P9_MINMAX"
5037   "xscmp%V1dp %x0,%x2,%x3"
5038   [(set_attr "type" "fpcompare")])
5040 (define_insn "*xxsel<mode>"
5041   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5042         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5043                                (match_operand:V2DI 2 "zero_constant" ""))
5044                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5045                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5046   "TARGET_P9_MINMAX"
5047   "xxsel %x0,%x4,%x3,%x1"
5048   [(set_attr "type" "vecmove")])
5051 ;; Conversions to and from floating-point.
5053 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5054 ; don't want to support putting SImode in FPR registers.
5055 (define_insn "lfiwax"
5056   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5057         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5058                    UNSPEC_LFIWAX))]
5059   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5060   "@
5061    lfiwax %0,%y1
5062    lxsiwax %x0,%y1
5063    mtvsrwa %x0,%1
5064    vextsw2d %0,%1"
5065   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5067 ; This split must be run before register allocation because it allocates the
5068 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5069 ; it earlier to allow for the combiner to merge insns together where it might
5070 ; not be needed and also in case the insns are deleted as dead code.
5072 (define_insn_and_split "floatsi<mode>2_lfiwax"
5073   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5074         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5075    (clobber (match_scratch:DI 2 "=wi"))]
5076   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5077    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5078   "#"
5079   ""
5080   [(pc)]
5081   "
5083   rtx dest = operands[0];
5084   rtx src = operands[1];
5085   rtx tmp;
5087   if (!MEM_P (src) && TARGET_POWERPC64
5088       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5089     tmp = convert_to_mode (DImode, src, false);
5090   else
5091     {
5092       tmp = operands[2];
5093       if (GET_CODE (tmp) == SCRATCH)
5094         tmp = gen_reg_rtx (DImode);
5095       if (MEM_P (src))
5096         {
5097           src = rs6000_address_for_fpconvert (src);
5098           emit_insn (gen_lfiwax (tmp, src));
5099         }
5100       else
5101         {
5102           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5103           emit_move_insn (stack, src);
5104           emit_insn (gen_lfiwax (tmp, stack));
5105         }
5106     }
5107   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5108   DONE;
5110   [(set_attr "length" "12")
5111    (set_attr "type" "fpload")])
5113 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5114   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5115         (float:SFDF
5116          (sign_extend:DI
5117           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5118    (clobber (match_scratch:DI 2 "=wi"))]
5119   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5120    && <SI_CONVERT_FP>"
5121   "#"
5122   ""
5123   [(pc)]
5124   "
5126   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5127   if (GET_CODE (operands[2]) == SCRATCH)
5128     operands[2] = gen_reg_rtx (DImode);
5129   if (TARGET_VSX_SMALL_INTEGER)
5130     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5131   else
5132     emit_insn (gen_lfiwax (operands[2], operands[1]));
5133   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5134   DONE;
5136   [(set_attr "length" "8")
5137    (set_attr "type" "fpload")])
5139 (define_insn "lfiwzx"
5140   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5141         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5142                    UNSPEC_LFIWZX))]
5143   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5144   "@
5145    lfiwzx %0,%y1
5146    lxsiwzx %x0,%y1
5147    mtvsrwz %x0,%1
5148    xxextractuw %x0,%x1,4"
5149   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5151 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5152   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5153         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5154    (clobber (match_scratch:DI 2 "=wi"))]
5155   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5156    && <SI_CONVERT_FP>"
5157   "#"
5158   ""
5159   [(pc)]
5160   "
5162   rtx dest = operands[0];
5163   rtx src = operands[1];
5164   rtx tmp;
5166   if (!MEM_P (src) && TARGET_POWERPC64
5167       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5168     tmp = convert_to_mode (DImode, src, true);
5169   else
5170     {
5171       tmp = operands[2];
5172       if (GET_CODE (tmp) == SCRATCH)
5173         tmp = gen_reg_rtx (DImode);
5174       if (MEM_P (src))
5175         {
5176           src = rs6000_address_for_fpconvert (src);
5177           emit_insn (gen_lfiwzx (tmp, src));
5178         }
5179       else
5180         {
5181           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5182           emit_move_insn (stack, src);
5183           emit_insn (gen_lfiwzx (tmp, stack));
5184         }
5185     }
5186   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5187   DONE;
5189   [(set_attr "length" "12")
5190    (set_attr "type" "fpload")])
5192 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5193   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5194         (unsigned_float:SFDF
5195          (zero_extend:DI
5196           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5197    (clobber (match_scratch:DI 2 "=wi"))]
5198   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5199    && <SI_CONVERT_FP>"
5200   "#"
5201   ""
5202   [(pc)]
5203   "
5205   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5206   if (GET_CODE (operands[2]) == SCRATCH)
5207     operands[2] = gen_reg_rtx (DImode);
5208   if (TARGET_VSX_SMALL_INTEGER)
5209     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5210   else
5211     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5212   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5213   DONE;
5215   [(set_attr "length" "8")
5216    (set_attr "type" "fpload")])
5218 ; For each of these conversions, there is a define_expand, a define_insn
5219 ; with a '#' template, and a define_split (with C code).  The idea is
5220 ; to allow constant folding with the template of the define_insn,
5221 ; then to have the insns split later (between sched1 and final).
5223 (define_expand "floatsidf2"
5224   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5225                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5226               (use (match_dup 2))
5227               (use (match_dup 3))
5228               (clobber (match_dup 4))
5229               (clobber (match_dup 5))
5230               (clobber (match_dup 6))])]
5231   "TARGET_HARD_FLOAT 
5232    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5233   "
5235   if (TARGET_E500_DOUBLE)
5236     {
5237       if (!REG_P (operands[1]))
5238         operands[1] = force_reg (SImode, operands[1]);
5239       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5240       DONE;
5241     }
5242   else if (TARGET_LFIWAX && TARGET_FCFID)
5243     {
5244       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5245       DONE;
5246     }
5247   else if (TARGET_FCFID)
5248     {
5249       rtx dreg = operands[1];
5250       if (!REG_P (dreg))
5251         dreg = force_reg (SImode, dreg);
5252       dreg = convert_to_mode (DImode, dreg, false);
5253       emit_insn (gen_floatdidf2 (operands[0], dreg));
5254       DONE;
5255     }
5257   if (!REG_P (operands[1]))
5258     operands[1] = force_reg (SImode, operands[1]);
5259   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5260   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5261   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5262   operands[5] = gen_reg_rtx (DFmode);
5263   operands[6] = gen_reg_rtx (SImode);
5266 (define_insn_and_split "*floatsidf2_internal"
5267   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5268         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5269    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5270    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5271    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5272    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5273    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5274   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5275   "#"
5276   ""
5277   [(pc)]
5278   "
5280   rtx lowword, highword;
5281   gcc_assert (MEM_P (operands[4]));
5282   highword = adjust_address (operands[4], SImode, 0);
5283   lowword = adjust_address (operands[4], SImode, 4);
5284   if (! WORDS_BIG_ENDIAN)
5285     std::swap (lowword, highword);
5287   emit_insn (gen_xorsi3 (operands[6], operands[1],
5288                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5289   emit_move_insn (lowword, operands[6]);
5290   emit_move_insn (highword, operands[2]);
5291   emit_move_insn (operands[5], operands[4]);
5292   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5293   DONE;
5295   [(set_attr "length" "24")
5296    (set_attr "type" "fp")])
5298 ;; If we don't have a direct conversion to single precision, don't enable this
5299 ;; conversion for 32-bit without fast math, because we don't have the insn to
5300 ;; generate the fixup swizzle to avoid double rounding problems.
5301 (define_expand "floatunssisf2"
5302   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5303         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5304   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5305    && (!TARGET_FPRS
5306        || (TARGET_FPRS
5307            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5308                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5309                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5310   "
5312   if (!TARGET_FPRS)
5313     {
5314       if (!REG_P (operands[1]))
5315         operands[1] = force_reg (SImode, operands[1]);
5316     }
5317   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5318     {
5319       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5320       DONE;
5321     }
5322   else
5323     {
5324       rtx dreg = operands[1];
5325       if (!REG_P (dreg))
5326         dreg = force_reg (SImode, dreg);
5327       dreg = convert_to_mode (DImode, dreg, true);
5328       emit_insn (gen_floatdisf2 (operands[0], dreg));
5329       DONE;
5330     }
5333 (define_expand "floatunssidf2"
5334   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5335                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5336               (use (match_dup 2))
5337               (use (match_dup 3))
5338               (clobber (match_dup 4))
5339               (clobber (match_dup 5))])]
5340   "TARGET_HARD_FLOAT
5341    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5342   "
5344   if (TARGET_E500_DOUBLE)
5345     {
5346       if (!REG_P (operands[1]))
5347         operands[1] = force_reg (SImode, operands[1]);
5348       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5349       DONE;
5350     }
5351   else if (TARGET_LFIWZX && TARGET_FCFID)
5352     {
5353       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5354       DONE;
5355     }
5356   else if (TARGET_FCFID)
5357     {
5358       rtx dreg = operands[1];
5359       if (!REG_P (dreg))
5360         dreg = force_reg (SImode, dreg);
5361       dreg = convert_to_mode (DImode, dreg, true);
5362       emit_insn (gen_floatdidf2 (operands[0], dreg));
5363       DONE;
5364     }
5366   if (!REG_P (operands[1]))
5367     operands[1] = force_reg (SImode, operands[1]);
5368   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5369   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5370   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5371   operands[5] = gen_reg_rtx (DFmode);
5374 (define_insn_and_split "*floatunssidf2_internal"
5375   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5376         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5377    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5378    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5379    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5380    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5381   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5382    && !(TARGET_FCFID && TARGET_POWERPC64)"
5383   "#"
5384   ""
5385   [(pc)]
5386   "
5388   rtx lowword, highword;
5389   gcc_assert (MEM_P (operands[4]));
5390   highword = adjust_address (operands[4], SImode, 0);
5391   lowword = adjust_address (operands[4], SImode, 4);
5392   if (! WORDS_BIG_ENDIAN)
5393     std::swap (lowword, highword);
5395   emit_move_insn (lowword, operands[1]);
5396   emit_move_insn (highword, operands[2]);
5397   emit_move_insn (operands[5], operands[4]);
5398   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5399   DONE;
5401   [(set_attr "length" "20")
5402    (set_attr "type" "fp")])
5404 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5405 ;; vector registers.  These insns favor doing the sign/zero extension in
5406 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5407 ;; extension and then a direct move.
5409 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5410   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5411                    (float:FP_ISA3
5412                     (match_operand:QHI 1 "input_operand")))
5413               (clobber (match_scratch:DI 2))
5414               (clobber (match_scratch:DI 3))
5415               (clobber (match_scratch:<QHI:MODE> 4))])]
5416   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5417    && TARGET_VSX_SMALL_INTEGER"
5419   if (MEM_P (operands[1]))
5420     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5423 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5424   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5425         (float:FP_ISA3
5426          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5427    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5428    (clobber (match_scratch:DI 3 "=X,r,X"))
5429    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5430   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5431    && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5432   "#"
5433   "&& reload_completed"
5434   [(const_int 0)]
5436   rtx result = operands[0];
5437   rtx input = operands[1];
5438   rtx di = operands[2];
5440   if (!MEM_P (input))
5441     {
5442       rtx tmp = operands[3];
5443       if (altivec_register_operand (input, <QHI:MODE>mode))
5444         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5445       else if (GET_CODE (tmp) == SCRATCH)
5446         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5447       else
5448         {
5449           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5450           emit_move_insn (di, tmp);
5451         }
5452     }
5453   else
5454     {
5455       rtx tmp = operands[4];
5456       emit_move_insn (tmp, input);
5457       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5458     }
5460   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5461   DONE;
5464 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5465   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5466                    (unsigned_float:FP_ISA3
5467                     (match_operand:QHI 1 "input_operand" "")))
5468               (clobber (match_scratch:DI 2 ""))
5469               (clobber (match_scratch:DI 3 ""))])]
5470   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5471    && TARGET_VSX_SMALL_INTEGER"
5473   if (MEM_P (operands[1]))
5474     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5477 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5478   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5479         (unsigned_float:FP_ISA3
5480          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5481    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5482    (clobber (match_scratch:DI 3 "=X,r,X"))]
5483   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5484    && TARGET_VSX_SMALL_INTEGER"
5485   "#"
5486   "&& reload_completed"
5487   [(const_int 0)]
5489   rtx result = operands[0];
5490   rtx input = operands[1];
5491   rtx di = operands[2];
5493   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5494     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5495   else
5496     {
5497       rtx tmp = operands[3];
5498       if (GET_CODE (tmp) == SCRATCH)
5499         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5500       else
5501         {
5502           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5503           emit_move_insn (di, tmp);
5504         }
5505     }
5507   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5508   DONE;
5511 (define_expand "fix_trunc<mode>si2"
5512   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5513         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5514   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5515   "
5517   if (!<E500_CONVERT>)
5518     {
5519       rtx src = force_reg (<MODE>mode, operands[1]);
5521       if (TARGET_STFIWX)
5522         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5523       else
5524         {
5525           rtx tmp = gen_reg_rtx (DImode);
5526           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5527           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5528                                                       tmp, stack));
5529         }
5530       DONE;
5531     }
5534 ; Like the convert to float patterns, this insn must be split before
5535 ; register allocation so that it can allocate the memory slot if it
5536 ; needed
5537 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5538   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5539         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5540    (clobber (match_scratch:DI 2 "=d"))]
5541   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5542    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5543    && TARGET_STFIWX && can_create_pseudo_p ()"
5544   "#"
5545   ""
5546   [(pc)]
5548   rtx dest = operands[0];
5549   rtx src = operands[1];
5550   rtx tmp = operands[2];
5552   if (GET_CODE (tmp) == SCRATCH)
5553     tmp = gen_reg_rtx (DImode);
5555   emit_insn (gen_fctiwz_<mode> (tmp, src));
5556   if (MEM_P (dest))
5557     {
5558       dest = rs6000_address_for_fpconvert (dest);
5559       emit_insn (gen_stfiwx (dest, tmp));
5560       DONE;
5561     }
5562   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5563     {
5564       dest = gen_lowpart (DImode, dest);
5565       emit_move_insn (dest, tmp);
5566       DONE;
5567     }
5568   else
5569     {
5570       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5571       emit_insn (gen_stfiwx (stack, tmp));
5572       emit_move_insn (dest, stack);
5573       DONE;
5574     }
5576   [(set_attr "length" "12")
5577    (set_attr "type" "fp")])
5579 (define_insn_and_split "fix_trunc<mode>si2_internal"
5580   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5581         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5582    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5583    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5584   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5585   "#"
5586   ""
5587   [(pc)]
5588   "
5590   rtx lowword;
5591   gcc_assert (MEM_P (operands[3]));
5592   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5594   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5595   emit_move_insn (operands[3], operands[2]);
5596   emit_move_insn (operands[0], lowword);
5597   DONE;
5599   [(set_attr "length" "16")
5600    (set_attr "type" "fp")])
5602 (define_expand "fix_trunc<mode>di2"
5603   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5604         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5605   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5606    && TARGET_FCFID"
5607   "")
5609 (define_insn "*fix_trunc<mode>di2_fctidz"
5610   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5611         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5612   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5613     && TARGET_FCFID"
5614   "@
5615    fctidz %0,%1
5616    xscvdpsxds %x0,%x1"
5617   [(set_attr "type" "fp")])
5619 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5620   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5621                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5622               (clobber (match_scratch:DI 2))])]
5623   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5624    && TARGET_VSX_SMALL_INTEGER"
5626   if (MEM_P (operands[0]))
5627     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5630 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5631   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5632         (fix:QHI
5633          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5634    (clobber (match_scratch:DI 2 "=X,wi"))]
5635   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5636    && TARGET_VSX_SMALL_INTEGER"
5637   "#"
5638   "&& reload_completed"
5639   [(const_int 0)]
5641   rtx dest = operands[0];
5642   rtx src = operands[1];
5644   if (vsx_register_operand (dest, <QHI:MODE>mode))
5645     {
5646       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5647       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5648     }
5649   else
5650     {
5651       rtx tmp = operands[2];
5652       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5654       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5655       emit_move_insn (dest, tmp2);
5656     }
5657   DONE;
5660 (define_expand "fixuns_trunc<mode>si2"
5661   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5662         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5663   "TARGET_HARD_FLOAT
5664    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5665        || <E500_CONVERT>)"
5666   "
5668   if (!<E500_CONVERT>)
5669     {
5670       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5671       DONE;
5672     }
5675 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5676   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5677         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5678    (clobber (match_scratch:DI 2 "=d"))]
5679   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5680    && TARGET_STFIWX && can_create_pseudo_p ()"
5681   "#"
5682   ""
5683   [(pc)]
5685   rtx dest = operands[0];
5686   rtx src = operands[1];
5687   rtx tmp = operands[2];
5689   if (GET_CODE (tmp) == SCRATCH)
5690     tmp = gen_reg_rtx (DImode);
5692   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5693   if (MEM_P (dest))
5694     {
5695       dest = rs6000_address_for_fpconvert (dest);
5696       emit_insn (gen_stfiwx (dest, tmp));
5697       DONE;
5698     }
5699   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5700     {
5701       dest = gen_lowpart (DImode, dest);
5702       emit_move_insn (dest, tmp);
5703       DONE;
5704     }
5705   else
5706     {
5707       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5708       emit_insn (gen_stfiwx (stack, tmp));
5709       emit_move_insn (dest, stack);
5710       DONE;
5711     }
5713   [(set_attr "length" "12")
5714    (set_attr "type" "fp")])
5716 (define_expand "fixuns_trunc<mode>di2"
5717   [(set (match_operand:DI 0 "register_operand" "")
5718         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5719   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5720   "")
5722 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5723   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5724         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5725   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5726     && TARGET_FCTIDUZ"
5727   "@
5728    fctiduz %0,%1
5729    xscvdpuxds %x0,%x1"
5730   [(set_attr "type" "fp")])
5732 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5733   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5734                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5735               (clobber (match_scratch:DI 2))])]
5736   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5737    && TARGET_VSX_SMALL_INTEGER"
5739   if (MEM_P (operands[0]))
5740     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5743 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5744   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5745         (unsigned_fix:QHI
5746          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5747    (clobber (match_scratch:DI 2 "=X,wi"))]
5748   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5749    && TARGET_VSX_SMALL_INTEGER"
5750   "#"
5751   "&& reload_completed"
5752   [(const_int 0)]
5754   rtx dest = operands[0];
5755   rtx src = operands[1];
5757   if (vsx_register_operand (dest, <QHI:MODE>mode))
5758     {
5759       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5760       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5761     }
5762   else
5763     {
5764       rtx tmp = operands[2];
5765       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5767       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5768       emit_move_insn (dest, tmp2);
5769     }
5770   DONE;
5772 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5773 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5774 ; because the first makes it clear that operand 0 is not live
5775 ; before the instruction.
5776 (define_insn "fctiwz_<mode>"
5777   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5778         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5779                    UNSPEC_FCTIWZ))]
5780   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5781   "@
5782    fctiwz %0,%1
5783    xscvdpsxws %x0,%x1"
5784   [(set_attr "type" "fp")])
5786 (define_insn "fctiwuz_<mode>"
5787   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5788         (unspec:DI [(unsigned_fix:SI
5789                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5790                    UNSPEC_FCTIWUZ))]
5791   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5792   "@
5793    fctiwuz %0,%1
5794    xscvdpuxws %x0,%x1"
5795   [(set_attr "type" "fp")])
5797 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5798 ;; since the friz instruction does not truncate the value if the floating
5799 ;; point value is < LONG_MIN or > LONG_MAX.
5800 (define_insn "*friz"
5801   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5802         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5803   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5804    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5805   "@
5806    friz %0,%1
5807    xsrdpiz %x0,%x1"
5808   [(set_attr "type" "fp")])
5810 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5811 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5812 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5813 ;; extend it, store it back on the stack from the GPR, load it back into the
5814 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5815 ;; disable using store and load to sign/zero extend the value.
5816 (define_insn_and_split "*round32<mode>2_fprs"
5817   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5818         (float:SFDF
5819          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5820    (clobber (match_scratch:DI 2 "=d"))
5821    (clobber (match_scratch:DI 3 "=d"))]
5822   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5823    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5824    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5825   "#"
5826   ""
5827   [(pc)]
5829   rtx dest = operands[0];
5830   rtx src = operands[1];
5831   rtx tmp1 = operands[2];
5832   rtx tmp2 = operands[3];
5833   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5835   if (GET_CODE (tmp1) == SCRATCH)
5836     tmp1 = gen_reg_rtx (DImode);
5837   if (GET_CODE (tmp2) == SCRATCH)
5838     tmp2 = gen_reg_rtx (DImode);
5840   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5841   emit_insn (gen_stfiwx (stack, tmp1));
5842   emit_insn (gen_lfiwax (tmp2, stack));
5843   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5844   DONE;
5846   [(set_attr "type" "fpload")
5847    (set_attr "length" "16")])
5849 (define_insn_and_split "*roundu32<mode>2_fprs"
5850   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5851         (unsigned_float:SFDF
5852          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5853    (clobber (match_scratch:DI 2 "=d"))
5854    (clobber (match_scratch:DI 3 "=d"))]
5855   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5856    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5857    && can_create_pseudo_p ()"
5858   "#"
5859   ""
5860   [(pc)]
5862   rtx dest = operands[0];
5863   rtx src = operands[1];
5864   rtx tmp1 = operands[2];
5865   rtx tmp2 = operands[3];
5866   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5868   if (GET_CODE (tmp1) == SCRATCH)
5869     tmp1 = gen_reg_rtx (DImode);
5870   if (GET_CODE (tmp2) == SCRATCH)
5871     tmp2 = gen_reg_rtx (DImode);
5873   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5874   emit_insn (gen_stfiwx (stack, tmp1));
5875   emit_insn (gen_lfiwzx (tmp2, stack));
5876   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5877   DONE;
5879   [(set_attr "type" "fpload")
5880    (set_attr "length" "16")])
5882 ;; No VSX equivalent to fctid
5883 (define_insn "lrint<mode>di2"
5884   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5885         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5886                    UNSPEC_FCTID))]
5887   "TARGET_<MODE>_FPR && TARGET_FPRND"
5888   "fctid %0,%1"
5889   [(set_attr "type" "fp")])
5891 (define_insn "btrunc<mode>2"
5892   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5893         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5894                      UNSPEC_FRIZ))]
5895   "TARGET_<MODE>_FPR && TARGET_FPRND"
5896   "@
5897    friz %0,%1
5898    xsrdpiz %x0,%x1"
5899   [(set_attr "type" "fp")
5900    (set_attr "fp_type" "fp_addsub_<Fs>")])
5902 (define_insn "ceil<mode>2"
5903   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5904         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5905                      UNSPEC_FRIP))]
5906   "TARGET_<MODE>_FPR && TARGET_FPRND"
5907   "@
5908    frip %0,%1
5909    xsrdpip %x0,%x1"
5910   [(set_attr "type" "fp")
5911    (set_attr "fp_type" "fp_addsub_<Fs>")])
5913 (define_insn "floor<mode>2"
5914   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5915         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5916                      UNSPEC_FRIM))]
5917   "TARGET_<MODE>_FPR && TARGET_FPRND"
5918   "@
5919    frim %0,%1
5920    xsrdpim %x0,%x1"
5921   [(set_attr "type" "fp")
5922    (set_attr "fp_type" "fp_addsub_<Fs>")])
5924 ;; No VSX equivalent to frin
5925 (define_insn "round<mode>2"
5926   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5927         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5928                      UNSPEC_FRIN))]
5929   "TARGET_<MODE>_FPR && TARGET_FPRND"
5930   "frin %0,%1"
5931   [(set_attr "type" "fp")
5932    (set_attr "fp_type" "fp_addsub_<Fs>")])
5934 (define_insn "*xsrdpi<mode>2"
5935   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5936         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5937                      UNSPEC_XSRDPI))]
5938   "TARGET_<MODE>_FPR && TARGET_VSX"
5939   "xsrdpi %x0,%x1"
5940   [(set_attr "type" "fp")
5941    (set_attr "fp_type" "fp_addsub_<Fs>")])
5943 (define_expand "lround<mode>di2"
5944   [(set (match_dup 2)
5945         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5946                      UNSPEC_XSRDPI))
5947    (set (match_operand:DI 0 "gpc_reg_operand" "")
5948         (unspec:DI [(match_dup 2)]
5949                    UNSPEC_FCTID))]
5950   "TARGET_<MODE>_FPR && TARGET_VSX"
5952   operands[2] = gen_reg_rtx (<MODE>mode);
5955 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5956 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5957 ; is only generated for Power8 or later.
5958 (define_insn "stfiwx"
5959   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5960         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5961                    UNSPEC_STFIWX))]
5962   "TARGET_PPC_GFXOPT"
5963   "@
5964    stfiwx %1,%y0
5965    stxsiwx %x1,%y0"
5966   [(set_attr "type" "fpstore")])
5968 ;; If we don't have a direct conversion to single precision, don't enable this
5969 ;; conversion for 32-bit without fast math, because we don't have the insn to
5970 ;; generate the fixup swizzle to avoid double rounding problems.
5971 (define_expand "floatsisf2"
5972   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5973         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5974   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5975    && (!TARGET_FPRS
5976        || (TARGET_FPRS
5977            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5978                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5979                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5980   "
5982   if (!TARGET_FPRS)
5983     {
5984       if (!REG_P (operands[1]))
5985         operands[1] = force_reg (SImode, operands[1]);
5986     }
5987   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5988     {
5989       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5990       DONE;
5991     }
5992   else if (TARGET_FCFID && TARGET_LFIWAX)
5993     {
5994       rtx dfreg = gen_reg_rtx (DFmode);
5995       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5996       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5997       DONE;
5998     }
5999   else
6000     {
6001       rtx dreg = operands[1];
6002       if (!REG_P (dreg))
6003         dreg = force_reg (SImode, dreg);
6004       dreg = convert_to_mode (DImode, dreg, false);
6005       emit_insn (gen_floatdisf2 (operands[0], dreg));
6006       DONE;
6007     }
6010 (define_expand "floatdidf2"
6011   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6012         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6013   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6014   "")
6016 (define_insn "*floatdidf2_fpr"
6017   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6018         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6019   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6020   "@
6021    fcfid %0,%1
6022    xscvsxddp %x0,%x1"
6023   [(set_attr "type" "fp")])
6025 ; Allow the combiner to merge source memory operands to the conversion so that
6026 ; the optimizer/register allocator doesn't try to load the value too early in a
6027 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6028 ; hit.  We will split after reload to avoid the trip through the GPRs
6030 (define_insn_and_split "*floatdidf2_mem"
6031   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6032         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6033    (clobber (match_scratch:DI 2 "=d,wi"))]
6034   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6035   "#"
6036   "&& reload_completed"
6037   [(set (match_dup 2) (match_dup 1))
6038    (set (match_dup 0) (float:DF (match_dup 2)))]
6039   ""
6040   [(set_attr "length" "8")
6041    (set_attr "type" "fpload")])
6043 (define_expand "floatunsdidf2"
6044   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6045         (unsigned_float:DF
6046          (match_operand:DI 1 "gpc_reg_operand" "")))]
6047   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6048   "")
6050 (define_insn "*floatunsdidf2_fcfidu"
6051   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6052         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6053   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6054   "@
6055    fcfidu %0,%1
6056    xscvuxddp %x0,%x1"
6057   [(set_attr "type" "fp")
6058    (set_attr "length" "4")])
6060 (define_insn_and_split "*floatunsdidf2_mem"
6061   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6062         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6063    (clobber (match_scratch:DI 2 "=d,wi"))]
6064   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6065   "#"
6066   "&& reload_completed"
6067   [(set (match_dup 2) (match_dup 1))
6068    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6069   ""
6070   [(set_attr "length" "8")
6071    (set_attr "type" "fpload")])
6073 (define_expand "floatdisf2"
6074   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6075         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6076   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6077    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6078   "
6080   if (!TARGET_FCFIDS)
6081     {
6082       rtx val = operands[1];
6083       if (!flag_unsafe_math_optimizations)
6084         {
6085           rtx label = gen_label_rtx ();
6086           val = gen_reg_rtx (DImode);
6087           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6088           emit_label (label);
6089         }
6090       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6091       DONE;
6092     }
6095 (define_insn "floatdisf2_fcfids"
6096   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6097         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6098   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6099    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6100   "@
6101    fcfids %0,%1
6102    xscvsxdsp %x0,%x1"
6103   [(set_attr "type" "fp")])
6105 (define_insn_and_split "*floatdisf2_mem"
6106   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6107         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6108    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6109   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6110    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6111   "#"
6112   "&& reload_completed"
6113   [(pc)]
6114   "
6116   emit_move_insn (operands[2], operands[1]);
6117   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6118   DONE;
6120   [(set_attr "length" "8")])
6122 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6123 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6124 ;; from double rounding.
6125 ;; Instead of creating a new cpu type for two FP operations, just use fp
6126 (define_insn_and_split "floatdisf2_internal1"
6127   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6128         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6129    (clobber (match_scratch:DF 2 "=d"))]
6130   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6131    && !TARGET_FCFIDS"
6132   "#"
6133   "&& reload_completed"
6134   [(set (match_dup 2)
6135         (float:DF (match_dup 1)))
6136    (set (match_dup 0)
6137         (float_truncate:SF (match_dup 2)))]
6138   ""
6139   [(set_attr "length" "8")
6140    (set_attr "type" "fp")])
6142 ;; Twiddles bits to avoid double rounding.
6143 ;; Bits that might be truncated when converting to DFmode are replaced
6144 ;; by a bit that won't be lost at that stage, but is below the SFmode
6145 ;; rounding position.
6146 (define_expand "floatdisf2_internal2"
6147   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6148                                               (const_int 53)))
6149               (clobber (reg:DI CA_REGNO))])
6150    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6151                                            (const_int 2047)))
6152    (set (match_dup 3) (plus:DI (match_dup 3)
6153                                (const_int 1)))
6154    (set (match_dup 0) (plus:DI (match_dup 0)
6155                                (const_int 2047)))
6156    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6157                                      (const_int 2)))
6158    (set (match_dup 0) (ior:DI (match_dup 0)
6159                               (match_dup 1)))
6160    (set (match_dup 0) (and:DI (match_dup 0)
6161                               (const_int -2048)))
6162    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6163                            (label_ref (match_operand:DI 2 "" ""))
6164                            (pc)))
6165    (set (match_dup 0) (match_dup 1))]
6166   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6167    && !TARGET_FCFIDS"
6168   "
6170   operands[3] = gen_reg_rtx (DImode);
6171   operands[4] = gen_reg_rtx (CCUNSmode);
6174 (define_expand "floatunsdisf2"
6175   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6176         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6177   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6178    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6179   "")
6181 (define_insn "floatunsdisf2_fcfidus"
6182   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6183         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6184   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6185    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6186   "@
6187    fcfidus %0,%1
6188    xscvuxdsp %x0,%x1"
6189   [(set_attr "type" "fp")])
6191 (define_insn_and_split "*floatunsdisf2_mem"
6192   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6193         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6194    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6195   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6196    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6197   "#"
6198   "&& reload_completed"
6199   [(pc)]
6200   "
6202   emit_move_insn (operands[2], operands[1]);
6203   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6204   DONE;
6206   [(set_attr "length" "8")
6207    (set_attr "type" "fpload")])
6209 ;; Define the TImode operations that can be done in a small number
6210 ;; of instructions.  The & constraints are to prevent the register
6211 ;; allocator from allocating registers that overlap with the inputs
6212 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6213 ;; also allow for the output being the same as one of the inputs.
6215 (define_expand "addti3"
6216   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6217         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6218                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6219   "TARGET_64BIT"
6221   rtx lo0 = gen_lowpart (DImode, operands[0]);
6222   rtx lo1 = gen_lowpart (DImode, operands[1]);
6223   rtx lo2 = gen_lowpart (DImode, operands[2]);
6224   rtx hi0 = gen_highpart (DImode, operands[0]);
6225   rtx hi1 = gen_highpart (DImode, operands[1]);
6226   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6228   if (!reg_or_short_operand (lo2, DImode))
6229     lo2 = force_reg (DImode, lo2);
6230   if (!adde_operand (hi2, DImode))
6231     hi2 = force_reg (DImode, hi2);
6233   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6234   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6235   DONE;
6238 (define_expand "subti3"
6239   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6240         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6241                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6242   "TARGET_64BIT"
6244   rtx lo0 = gen_lowpart (DImode, operands[0]);
6245   rtx lo1 = gen_lowpart (DImode, operands[1]);
6246   rtx lo2 = gen_lowpart (DImode, operands[2]);
6247   rtx hi0 = gen_highpart (DImode, operands[0]);
6248   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6249   rtx hi2 = gen_highpart (DImode, operands[2]);
6251   if (!reg_or_short_operand (lo1, DImode))
6252     lo1 = force_reg (DImode, lo1);
6253   if (!adde_operand (hi1, DImode))
6254     hi1 = force_reg (DImode, hi1);
6256   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6257   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6258   DONE;
6261 ;; 128-bit logical operations expanders
6263 (define_expand "and<mode>3"
6264   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6265         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6266                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6267   ""
6268   "")
6270 (define_expand "ior<mode>3"
6271   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6272         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6273                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6274   ""
6275   "")
6277 (define_expand "xor<mode>3"
6278   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6279         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6280                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6281   ""
6282   "")
6284 (define_expand "one_cmpl<mode>2"
6285   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6286         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6287   ""
6288   "")
6290 (define_expand "nor<mode>3"
6291   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6292         (and:BOOL_128
6293          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6294          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6295   ""
6296   "")
6298 (define_expand "andc<mode>3"
6299   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6300         (and:BOOL_128
6301          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6302          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6303   ""
6304   "")
6306 ;; Power8 vector logical instructions.
6307 (define_expand "eqv<mode>3"
6308   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6309         (not:BOOL_128
6310          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6311                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6312   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6313   "")
6315 ;; Rewrite nand into canonical form
6316 (define_expand "nand<mode>3"
6317   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6318         (ior:BOOL_128
6319          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6320          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6321   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6322   "")
6324 ;; The canonical form is to have the negated element first, so we need to
6325 ;; reverse arguments.
6326 (define_expand "orc<mode>3"
6327   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6328         (ior:BOOL_128
6329          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6330          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6331   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6332   "")
6334 ;; 128-bit logical operations insns and split operations
6335 (define_insn_and_split "*and<mode>3_internal"
6336   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6337         (and:BOOL_128
6338          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6339          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6340   ""
6342   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6343     return "xxland %x0,%x1,%x2";
6345   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6346     return "vand %0,%1,%2";
6348   return "#";
6350   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6351   [(const_int 0)]
6353   rs6000_split_logical (operands, AND, false, false, false);
6354   DONE;
6356   [(set (attr "type")
6357       (if_then_else
6358         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6359         (const_string "veclogical")
6360         (const_string "integer")))
6361    (set (attr "length")
6362       (if_then_else
6363         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6364         (const_string "4")
6365         (if_then_else
6366          (match_test "TARGET_POWERPC64")
6367          (const_string "8")
6368          (const_string "16"))))])
6370 ;; 128-bit IOR/XOR
6371 (define_insn_and_split "*bool<mode>3_internal"
6372   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6373         (match_operator:BOOL_128 3 "boolean_or_operator"
6374          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6375           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6376   ""
6378   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6379     return "xxl%q3 %x0,%x1,%x2";
6381   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6382     return "v%q3 %0,%1,%2";
6384   return "#";
6386   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6387   [(const_int 0)]
6389   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6390   DONE;
6392   [(set (attr "type")
6393       (if_then_else
6394         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395         (const_string "veclogical")
6396         (const_string "integer")))
6397    (set (attr "length")
6398       (if_then_else
6399         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6400         (const_string "4")
6401         (if_then_else
6402          (match_test "TARGET_POWERPC64")
6403          (const_string "8")
6404          (const_string "16"))))])
6406 ;; 128-bit ANDC/ORC
6407 (define_insn_and_split "*boolc<mode>3_internal1"
6408   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6409         (match_operator:BOOL_128 3 "boolean_operator"
6410          [(not:BOOL_128
6411            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6412           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6413   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6415   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6416     return "xxl%q3 %x0,%x1,%x2";
6418   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6419     return "v%q3 %0,%1,%2";
6421   return "#";
6423   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6424    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6425   [(const_int 0)]
6427   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6428   DONE;
6430   [(set (attr "type")
6431       (if_then_else
6432         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6433         (const_string "veclogical")
6434         (const_string "integer")))
6435    (set (attr "length")
6436       (if_then_else
6437         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6438         (const_string "4")
6439         (if_then_else
6440          (match_test "TARGET_POWERPC64")
6441          (const_string "8")
6442          (const_string "16"))))])
6444 (define_insn_and_split "*boolc<mode>3_internal2"
6445   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6446         (match_operator:TI2 3 "boolean_operator"
6447          [(not:TI2
6448            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6449           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6450   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6451   "#"
6452   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6453   [(const_int 0)]
6455   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6456   DONE;
6458   [(set_attr "type" "integer")
6459    (set (attr "length")
6460         (if_then_else
6461          (match_test "TARGET_POWERPC64")
6462          (const_string "8")
6463          (const_string "16")))])
6465 ;; 128-bit NAND/NOR
6466 (define_insn_and_split "*boolcc<mode>3_internal1"
6467   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6468         (match_operator:BOOL_128 3 "boolean_operator"
6469          [(not:BOOL_128
6470            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6471           (not:BOOL_128
6472            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6473   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6475   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6476     return "xxl%q3 %x0,%x1,%x2";
6478   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6479     return "v%q3 %0,%1,%2";
6481   return "#";
6483   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6484    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6485   [(const_int 0)]
6487   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6488   DONE;
6490   [(set (attr "type")
6491       (if_then_else
6492         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6493         (const_string "veclogical")
6494         (const_string "integer")))
6495    (set (attr "length")
6496       (if_then_else
6497         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6498         (const_string "4")
6499         (if_then_else
6500          (match_test "TARGET_POWERPC64")
6501          (const_string "8")
6502          (const_string "16"))))])
6504 (define_insn_and_split "*boolcc<mode>3_internal2"
6505   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6506         (match_operator:TI2 3 "boolean_operator"
6507          [(not:TI2
6508            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6509           (not:TI2
6510            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6511   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6512   "#"
6513   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6514   [(const_int 0)]
6516   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6517   DONE;
6519   [(set_attr "type" "integer")
6520    (set (attr "length")
6521         (if_then_else
6522          (match_test "TARGET_POWERPC64")
6523          (const_string "8")
6524          (const_string "16")))])
6527 ;; 128-bit EQV
6528 (define_insn_and_split "*eqv<mode>3_internal1"
6529   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6530         (not:BOOL_128
6531          (xor:BOOL_128
6532           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6533           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6534   "TARGET_P8_VECTOR"
6536   if (vsx_register_operand (operands[0], <MODE>mode))
6537     return "xxleqv %x0,%x1,%x2";
6539   return "#";
6541   "TARGET_P8_VECTOR && reload_completed
6542    && int_reg_operand (operands[0], <MODE>mode)"
6543   [(const_int 0)]
6545   rs6000_split_logical (operands, XOR, true, false, false);
6546   DONE;
6548   [(set (attr "type")
6549       (if_then_else
6550         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6551         (const_string "veclogical")
6552         (const_string "integer")))
6553    (set (attr "length")
6554       (if_then_else
6555         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6556         (const_string "4")
6557         (if_then_else
6558          (match_test "TARGET_POWERPC64")
6559          (const_string "8")
6560          (const_string "16"))))])
6562 (define_insn_and_split "*eqv<mode>3_internal2"
6563   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6564         (not:TI2
6565          (xor:TI2
6566           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6567           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6568   "!TARGET_P8_VECTOR"
6569   "#"
6570   "reload_completed && !TARGET_P8_VECTOR"
6571   [(const_int 0)]
6573   rs6000_split_logical (operands, XOR, true, false, false);
6574   DONE;
6576   [(set_attr "type" "integer")
6577    (set (attr "length")
6578         (if_then_else
6579          (match_test "TARGET_POWERPC64")
6580          (const_string "8")
6581          (const_string "16")))])
6583 ;; 128-bit one's complement
6584 (define_insn_and_split "*one_cmpl<mode>3_internal"
6585   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6586         (not:BOOL_128
6587           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6588   ""
6590   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6591     return "xxlnor %x0,%x1,%x1";
6593   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6594     return "vnor %0,%1,%1";
6596   return "#";
6598   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6599   [(const_int 0)]
6601   rs6000_split_logical (operands, NOT, false, false, false);
6602   DONE;
6604   [(set (attr "type")
6605       (if_then_else
6606         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6607         (const_string "veclogical")
6608         (const_string "integer")))
6609    (set (attr "length")
6610       (if_then_else
6611         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6612         (const_string "4")
6613         (if_then_else
6614          (match_test "TARGET_POWERPC64")
6615          (const_string "8")
6616          (const_string "16"))))])
6619 ;; Now define ways of moving data around.
6621 ;; Set up a register with a value from the GOT table
6623 (define_expand "movsi_got"
6624   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6625         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6626                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6627   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6628   "
6630   if (GET_CODE (operands[1]) == CONST)
6631     {
6632       rtx offset = const0_rtx;
6633       HOST_WIDE_INT value;
6635       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6636       value = INTVAL (offset);
6637       if (value != 0)
6638         {
6639           rtx tmp = (!can_create_pseudo_p ()
6640                      ? operands[0]
6641                      : gen_reg_rtx (Pmode));
6642           emit_insn (gen_movsi_got (tmp, operands[1]));
6643           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6644           DONE;
6645         }
6646     }
6648   operands[2] = rs6000_got_register (operands[1]);
6651 (define_insn "*movsi_got_internal"
6652   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6653         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6654                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6655                    UNSPEC_MOVSI_GOT))]
6656   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6657   "lwz %0,%a1@got(%2)"
6658   [(set_attr "type" "load")])
6660 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6661 ;; didn't get allocated to a hard register.
6662 (define_split
6663   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6664         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6665                     (match_operand:SI 2 "memory_operand" "")]
6666                    UNSPEC_MOVSI_GOT))]
6667   "DEFAULT_ABI == ABI_V4
6668     && flag_pic == 1
6669     && (reload_in_progress || reload_completed)"
6670   [(set (match_dup 0) (match_dup 2))
6671    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6672                                  UNSPEC_MOVSI_GOT))]
6673   "")
6675 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6676 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6677 ;; and this is even supposed to be faster, but it is simpler not to get
6678 ;; integers in the TOC.
6679 (define_insn "movsi_low"
6680   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6681         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6682                            (match_operand 2 "" ""))))]
6683   "TARGET_MACHO && ! TARGET_64BIT"
6684   "lwz %0,lo16(%2)(%1)"
6685   [(set_attr "type" "load")
6686    (set_attr "length" "4")])
6688 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6689 ;;              STW          STFIWX       STXSIWX      LI           LIS
6690 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6691 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6692 ;;              MF%1         MT%0         MT%0         NOP
6693 (define_insn "*movsi_internal1"
6694   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6695                 "=r,         r,           r,           ?*wI,        ?*wH,
6696                  m,          ?Z,          ?Z,          r,           r,
6697                  r,          ?*wIwH,      ?*wJwK,      ?*wK,        ?*wJwK,
6698                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6699                  r,          *c*l,        *h,          *h")
6701         (match_operand:SI 1 "input_operand"
6702                 "r,          U,           m,           Z,           Z,
6703                  r,          wI,          wH,          I,           L,
6704                  n,          wIwH,        O,           wM,          wB,
6705                  O,          wM,          wS,          r,           wIwH,
6706                  *h,         r,           r,           0"))]
6708   "!TARGET_SINGLE_FPU &&
6709    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6710   "@
6711    mr %0,%1
6712    la %0,%a1
6713    lwz%U1%X1 %0,%1
6714    lfiwzx %0,%y1
6715    lxsiwzx %x0,%y1
6716    stw%U0%X0 %1,%0
6717    stfiwx %1,%y0
6718    stxsiwx %x1,%y0
6719    li %0,%1
6720    lis %0,%v1
6721    #
6722    xxlor %x0,%x1,%x1
6723    xxspltib %x0,0
6724    xxspltib %x0,255
6725    vspltisw %0,%1
6726    xxlxor %x0,%x0,%x0
6727    xxlorc %x0,%x0,%x0
6728    #
6729    mtvsrwz %x0,%1
6730    mfvsrwz %0,%x1
6731    mf%1 %0
6732    mt%0 %1
6733    mt%0 %1
6734    nop"
6735   [(set_attr "type"
6736                 "*,          *,           load,        fpload,      fpload,
6737                  store,      fpstore,     fpstore,     *,           *,
6738                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6739                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6740                  *,           *,           *,           *")
6742    (set_attr "length"
6743                 "4,          4,           4,           4,           4,
6744                  4,          4,           4,           4,           4,
6745                  8,          4,           4,           4,           4,
6746                  4,          4,           8,           4,           4,
6747                  4,          4,           4,           4")])
6749 (define_insn "*movsi_internal1_single"
6750   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6751         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6752   "TARGET_SINGLE_FPU &&
6753    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6754   "@
6755    mr %0,%1
6756    la %0,%a1
6757    lwz%U1%X1 %0,%1
6758    stw%U0%X0 %1,%0
6759    li %0,%1
6760    lis %0,%v1
6761    #
6762    mf%1 %0
6763    mt%0 %1
6764    mt%0 %1
6765    nop
6766    stfs%U0%X0 %1,%0
6767    lfs%U1%X1 %0,%1"
6768   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6769    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6771 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6772 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6774 ;; Because SF values are actually stored as DF values within the vector
6775 ;; registers, we need to convert the value to the vector SF format when
6776 ;; we need to use the bits in a union or similar cases.  We only need
6777 ;; to do this transformation when the value is a vector register.  Loads,
6778 ;; stores, and transfers within GPRs are assumed to be safe.
6780 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6781 ;; no alternatives, because the call is created as part of secondary_reload,
6782 ;; and operand #2's register class is used to allocate the temporary register.
6783 ;; This function is called before reload, and it creates the temporary as
6784 ;; needed.
6786 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6787 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  MTVSRWZ
6788 ;;              VSX->VSX
6790 (define_insn_and_split "movsi_from_sf"
6791   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6792                 "=r,         r,           ?*wI,        ?*wH,     m,
6793                  m,          wY,          Z,           r,        wIwH,
6794                  ?wK")
6796         (unspec:SI [(match_operand:SF 1 "input_operand"
6797                 "r,          m,           Z,           Z,        r,
6798                  f,          wu,          wu,          wIwH,     r,
6799                  wK")]
6800                     UNSPEC_SI_FROM_SF))
6802    (clobber (match_scratch:V4SF 2
6803                 "=X,         X,           X,           X,        X,
6804                  X,          X,           X,           wa,       X,
6805                  wa"))]
6807   "TARGET_NO_SF_SUBREG
6808    && (register_operand (operands[0], SImode)
6809        || register_operand (operands[1], SFmode))"
6810   "@
6811    mr %0,%1
6812    lwz%U1%X1 %0,%1
6813    lfiwzx %0,%y1
6814    lxsiwzx %x0,%y1
6815    stw%U0%X0 %1,%0
6816    stfs%U0%X0 %1,%0
6817    stxssp %1,%0
6818    stxsspx %x1,%y0
6819    #
6820    mtvsrwz %x0,%1
6821    #"
6822   "&& reload_completed
6823    && register_operand (operands[0], SImode)
6824    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6825   [(const_int 0)]
6827   rtx op0 = operands[0];
6828   rtx op1 = operands[1];
6829   rtx op2 = operands[2];
6830   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6832   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6834   if (int_reg_operand (op0, SImode))
6835     {
6836       emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6837       emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6838     }
6839   else
6840     {
6841       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6842       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6843       emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6844     }
6846   DONE;
6848   [(set_attr "type"
6849                 "*,          load,        fpload,      fpload,   store,
6850                  fpstore,    fpstore,     fpstore,     mftgpr,   mffgpr,
6851                  veclogical")
6853    (set_attr "length"
6854                 "4,          4,           4,           4,        4,
6855                  4,          4,           4,           12,       4,
6856                  8")])
6858 ;; movsi_from_sf with zero extension
6860 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6861 ;;              MTVSRWZ      VSX->VSX
6863 (define_insn_and_split "*movdi_from_sf_zero_ext"
6864   [(set (match_operand:DI 0 "gpc_reg_operand"
6865                 "=r,         r,           ?*wI,        ?*wH,     r,
6866                 wIwH,        ?wK")
6868         (zero_extend:DI
6869          (unspec:SI [(match_operand:SF 1 "input_operand"
6870                 "r,          m,           Z,           Z,        wIwH,
6871                  r,          wK")]
6872                     UNSPEC_SI_FROM_SF)))
6874    (clobber (match_scratch:V4SF 2
6875                 "=X,         X,           X,           X,        wa,
6876                  X,          wa"))]
6878   "TARGET_DIRECT_MOVE_64BIT
6879    && (register_operand (operands[0], DImode)
6880        || register_operand (operands[1], SImode))"
6881   "@
6882    rldicl %0,%1,0,32
6883    lwz%U1%X1 %0,%1
6884    lfiwzx %0,%y1
6885    lxsiwzx %x0,%y1
6886    #
6887    mtvsrwz %x0,%1
6888    #"
6889   "&& reload_completed
6890    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6891   [(const_int 0)]
6893   rtx op0 = operands[0];
6894   rtx op1 = operands[1];
6895   rtx op2 = operands[2];
6897   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6899   if (int_reg_operand (op0, DImode))
6900     {
6901       emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6902       emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6903     }
6904   else
6905     {
6906       rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6907       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6908       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6909       emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6910     }
6912   DONE;
6914   [(set_attr "type"
6915                 "*,          load,        fpload,      fpload,  mftgpr,
6916                  mffgpr,     veclogical")
6918    (set_attr "length"
6919                 "4,          4,           4,           4,        12,
6920                  4,          8")])
6922 ;; Split a load of a large constant into the appropriate two-insn
6923 ;; sequence.
6925 (define_split
6926   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6927         (match_operand:SI 1 "const_int_operand" ""))]
6928   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6929    && (INTVAL (operands[1]) & 0xffff) != 0"
6930   [(set (match_dup 0)
6931         (match_dup 2))
6932    (set (match_dup 0)
6933         (ior:SI (match_dup 0)
6934                 (match_dup 3)))]
6935   "
6937   if (rs6000_emit_set_const (operands[0], operands[1]))
6938     DONE;
6939   else
6940     FAIL;
6943 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6944 (define_split
6945   [(set (match_operand:DI 0 "altivec_register_operand")
6946         (match_operand:DI 1 "xxspltib_constant_split"))]
6947   "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6948   [(const_int 0)]
6950   rtx op0 = operands[0];
6951   rtx op1 = operands[1];
6952   int r = REGNO (op0);
6953   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6955   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6956   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6957   DONE;
6960 (define_insn "*mov<mode>_internal2"
6961   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6962         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6963                     (const_int 0)))
6964    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6965   ""
6966   "@
6967    cmp<wd>i %2,%0,0
6968    mr. %0,%1
6969    #"
6970   [(set_attr "type" "cmp,logical,cmp")
6971    (set_attr "dot" "yes")
6972    (set_attr "length" "4,4,8")])
6974 (define_split
6975   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6976         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6977                     (const_int 0)))
6978    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6979   "reload_completed"
6980   [(set (match_dup 0) (match_dup 1))
6981    (set (match_dup 2)
6982         (compare:CC (match_dup 0)
6983                     (const_int 0)))]
6984   "")
6986 (define_expand "mov<mode>"
6987   [(set (match_operand:INT 0 "general_operand" "")
6988         (match_operand:INT 1 "any_operand" ""))]
6989   ""
6990   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6992 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
6993 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
6994 ;;              MTVSRWZ     MF%1       MT%1       NOP
6995 (define_insn "*mov<mode>_internal"
6996   [(set (match_operand:QHI 0 "nonimmediate_operand"
6997                 "=r,        r,         ?*wJwK,    m,         Z,         r,
6998                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
6999                  ?*wJwK,    r,         *c*l,      *h")
7001         (match_operand:QHI 1 "input_operand"
7002                 "r,         m,         Z,         r,         wJwK,      i,
7003                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7004                  r,         *h,        r,         0"))]
7006   "gpc_reg_operand (operands[0], <MODE>mode)
7007    || gpc_reg_operand (operands[1], <MODE>mode)"
7008   "@
7009    mr %0,%1
7010    l<wd>z%U1%X1 %0,%1
7011    lxsi<wd>zx %x0,%y1
7012    st<wd>%U0%X0 %1,%0
7013    stxsi<wd>x %x1,%y0
7014    li %0,%1
7015    xxlor %x0,%x1,%x1
7016    xxspltib %x0,0
7017    xxspltib %x0,255
7018    vspltis<wd> %0,%1
7019    #
7020    mfvsrwz %0,%x1
7021    mtvsrwz %x0,%1
7022    mf%1 %0
7023    mt%0 %1
7024    nop"
7025   [(set_attr "type"
7026                 "*,         load,      fpload,    store,     fpstore,   *,
7027                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7028                  mffgpr,    mfjmpr,    mtjmpr,    *")
7030    (set_attr "length"
7031                 "4,         4,         4,         4,         4,         4,
7032                  4,         4,         4,         4,         8,         4,
7033                  4,         4,         4,         4")])
7036 ;; Here is how to move condition codes around.  When we store CC data in
7037 ;; an integer register or memory, we store just the high-order 4 bits.
7038 ;; This lets us not shift in the most common case of CR0.
7039 (define_expand "movcc"
7040   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7041         (match_operand:CC 1 "nonimmediate_operand" ""))]
7042   ""
7043   "")
7045 (define_insn "*movcc_internal1"
7046   [(set (match_operand:CC 0 "nonimmediate_operand"
7047                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7048         (match_operand:CC 1 "general_operand"
7049                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7050   "register_operand (operands[0], CCmode)
7051    || register_operand (operands[1], CCmode)"
7052   "@
7053    mcrf %0,%1
7054    mtcrf 128,%1
7055    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7056    crxor %0,%0,%0
7057    mfcr %0%Q1
7058    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7059    mr %0,%1
7060    li %0,%1
7061    mf%1 %0
7062    mt%0 %1
7063    lwz%U1%X1 %0,%1
7064    stw%U0%X0 %1,%0"
7065   [(set (attr "type")
7066      (cond [(eq_attr "alternative" "0,3")
7067                 (const_string "cr_logical")
7068             (eq_attr "alternative" "1,2")
7069                 (const_string "mtcr")
7070             (eq_attr "alternative" "6,7")
7071                 (const_string "integer")
7072             (eq_attr "alternative" "8")
7073                 (const_string "mfjmpr")
7074             (eq_attr "alternative" "9")
7075                 (const_string "mtjmpr")
7076             (eq_attr "alternative" "10")
7077                 (const_string "load")
7078             (eq_attr "alternative" "11")
7079                 (const_string "store")
7080             (match_test "TARGET_MFCRF")
7081                 (const_string "mfcrf")
7082            ]
7083         (const_string "mfcr")))
7084    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7086 ;; For floating-point, we normally deal with the floating-point registers
7087 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7088 ;; can produce floating-point values in fixed-point registers.  Unless the
7089 ;; value is a simple constant or already in memory, we deal with this by
7090 ;; allocating memory and copying the value explicitly via that memory location.
7092 ;; Move 32-bit binary/decimal floating point
7093 (define_expand "mov<mode>"
7094   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7095         (match_operand:FMOVE32 1 "any_operand" ""))]
7096   "<fmove_ok>"
7097   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7099 (define_split
7100   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7101         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7102   "reload_completed
7103    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7104        || (GET_CODE (operands[0]) == SUBREG
7105            && GET_CODE (SUBREG_REG (operands[0])) == REG
7106            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7107   [(set (match_dup 2) (match_dup 3))]
7108   "
7110   long l;
7112   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7114   if (! TARGET_POWERPC64)
7115     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7116   else
7117     operands[2] = gen_lowpart (SImode, operands[0]);
7119   operands[3] = gen_int_mode (l, SImode);
7122 (define_insn "mov<mode>_hardfloat"
7123   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7124          "=!r,       <f32_lr>,  <f32_lr2>, <f32_av>,  m,         <f32_sm>,
7125           <f32_sm2>, Z,         <f32_vsx>, !r,        ?<f32_dm>, ?r,
7126           f,         <f32_vsx>, !r,        *c*l,      !r,        *h")
7127         (match_operand:FMOVE32 1 "input_operand"
7128          "m,         <f32_lm>,  <f32_lm2>, Z,         r,         <f32_sr>,
7129           <f32_sr2>, <f32_av>,  <zero_fp>, <zero_fp>, r,         <f32_dm>,
7130           f,         <f32_vsx>, r,         r,         *h,        0"))]
7131   "(register_operand (operands[0], <MODE>mode)
7132    || register_operand (operands[1], <MODE>mode))
7133    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7134    && (TARGET_ALLOW_SF_SUBREG
7135        || valid_sf_si_move (operands[0], operands[1], <MODE>mode))"
7136   "@
7137    lwz%U1%X1 %0,%1
7138    <f32_li>
7139    <f32_li2>
7140    <f32_lv>
7141    stw%U0%X0 %1,%0
7142    <f32_si>
7143    <f32_si2>
7144    <f32_sv>
7145    xxlxor %x0,%x0,%x0
7146    li %0,0
7147    mtvsrwz %x0,%1
7148    mfvsrwz %0,%x1
7149    fmr %0,%1
7150    xscpsgndp %x0,%x1,%x1
7151    mr %0,%1
7152    mt%0 %1
7153    mf%1 %0
7154    nop"
7155   [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
7157 (define_insn "*mov<mode>_softfloat"
7158   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7159         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7160   "(gpc_reg_operand (operands[0], <MODE>mode)
7161    || gpc_reg_operand (operands[1], <MODE>mode))
7162    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7163   "@
7164    mr %0,%1
7165    mt%0 %1
7166    mf%1 %0
7167    lwz%U1%X1 %0,%1
7168    stw%U0%X0 %1,%0
7169    li %0,%1
7170    lis %0,%v1
7171    #
7172    #
7173    nop"
7174   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7175    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7177 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7178 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7180 ;; Because SF values are actually stored as DF values within the vector
7181 ;; registers, we need to convert the value to the vector SF format when
7182 ;; we need to use the bits in a union or similar cases.  We only need
7183 ;; to do this transformation when the value is a vector register.  Loads,
7184 ;; stores, and transfers within GPRs are assumed to be safe.
7186 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7187 ;; no alternatives, because the call is created as part of secondary_reload,
7188 ;; and operand #2's register class is used to allocate the temporary register.
7189 ;; This function is called before reload, and it creates the temporary as
7190 ;; needed.
7192 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7193 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7194 (define_insn_and_split "movsf_from_si"
7195   [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7196             "=!r,       f,         wb,        wu,        m,         Z,
7197              Z,         wy,        ?r,        !r")
7199         (unspec:SF [(match_operand:SI 1 "input_operand" 
7200             "m,         m,         wY,        Z,         r,         f,
7201              wu,        r,         wy,        r")]
7202                    UNSPEC_SF_FROM_SI))
7204    (clobber (match_scratch:DI 2
7205             "=X,        X,         X,         X,         X,         X,
7206              X,         r,         X,         X"))]
7208   "TARGET_NO_SF_SUBREG
7209    && (register_operand (operands[0], SFmode)
7210        || register_operand (operands[1], SImode))"
7211   "@
7212    lwz%U1%X1 %0,%1
7213    lfs%U1%X1 %0,%1
7214    lxssp %0,%1
7215    lxsspx %x0,%y1
7216    stw%U0%X0 %1,%0
7217    stfiwx %1,%y0
7218    stxsiwx %x1,%y0
7219    #
7220    mfvsrwz %0,%x1
7221    mr %0,%1"
7223   "&& reload_completed
7224    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7225    && int_reg_operand_not_pseudo (operands[1], SImode)"
7226   [(const_int 0)]
7228   rtx op0 = operands[0];
7229   rtx op1 = operands[1];
7230   rtx op2 = operands[2];
7231   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7233   /* Move SF value to upper 32-bits for xscvspdpn.  */
7234   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7235   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7236   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7237   DONE;
7239   [(set_attr "length"
7240             "4,          4,         4,         4,         4,         4,
7241              4,          12,        4,         4")
7242    (set_attr "type"
7243             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7244              fpstore,    vecfloat,  mffgpr,    *")])
7247 ;; Move 64-bit binary/decimal floating point
7248 (define_expand "mov<mode>"
7249   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7250         (match_operand:FMOVE64 1 "any_operand" ""))]
7251   ""
7252   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7254 (define_split
7255   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7256         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7257   "! TARGET_POWERPC64 && reload_completed
7258    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7259        || (GET_CODE (operands[0]) == SUBREG
7260            && GET_CODE (SUBREG_REG (operands[0])) == REG
7261            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7262   [(set (match_dup 2) (match_dup 4))
7263    (set (match_dup 3) (match_dup 1))]
7264   "
7266   int endian = (WORDS_BIG_ENDIAN == 0);
7267   HOST_WIDE_INT value = INTVAL (operands[1]);
7269   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7270   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7271   operands[4] = GEN_INT (value >> 32);
7272   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7275 (define_split
7276   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7277         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7278   "! TARGET_POWERPC64 && reload_completed
7279    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7280        || (GET_CODE (operands[0]) == SUBREG
7281            && GET_CODE (SUBREG_REG (operands[0])) == REG
7282            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7283   [(set (match_dup 2) (match_dup 4))
7284    (set (match_dup 3) (match_dup 5))]
7285   "
7287   int endian = (WORDS_BIG_ENDIAN == 0);
7288   long l[2];
7290   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7292   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7293   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7294   operands[4] = gen_int_mode (l[endian], SImode);
7295   operands[5] = gen_int_mode (l[1 - endian], SImode);
7298 (define_split
7299   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7300         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7301   "TARGET_POWERPC64 && reload_completed
7302    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7303        || (GET_CODE (operands[0]) == SUBREG
7304            && GET_CODE (SUBREG_REG (operands[0])) == REG
7305            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7306   [(set (match_dup 2) (match_dup 3))]
7307   "
7309   int endian = (WORDS_BIG_ENDIAN == 0);
7310   long l[2];
7311   HOST_WIDE_INT val;
7313   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7315   operands[2] = gen_lowpart (DImode, operands[0]);
7316   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7317   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7318          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7320   operands[3] = gen_int_mode (val, DImode);
7323 ;; Don't have reload use general registers to load a constant.  It is
7324 ;; less efficient than loading the constant into an FP register, since
7325 ;; it will probably be used there.
7327 ;; The move constraints are ordered to prefer floating point registers before
7328 ;; general purpose registers to avoid doing a store and a load to get the value
7329 ;; into a floating point register when it is needed for a floating point
7330 ;; operation.  Prefer traditional floating point registers over VSX registers,
7331 ;; since the D-form version of the memory instructions does not need a GPR for
7332 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7333 ;; registers.
7335 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7336 ;; except for 0.0 which can be created on VSX with an xor instruction.
7338 (define_insn "*mov<mode>_hardfloat32"
7339   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7340         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7341   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7342    && (gpc_reg_operand (operands[0], <MODE>mode)
7343        || gpc_reg_operand (operands[1], <MODE>mode))"
7344   "@
7345    stfd%U0%X0 %1,%0
7346    lfd%U1%X1 %0,%1
7347    fmr %0,%1
7348    lxsd%U1x %x0,%y1
7349    stxsd%U0x %x1,%y0
7350    lxsd %0,%1
7351    stxsd %1,%0
7352    xxlor %x0,%x1,%x1
7353    xxlxor %x0,%x0,%x0
7354    #
7355    #
7356    #
7357    #"
7358   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7359    (set_attr "size" "64")
7360    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7362 (define_insn "*mov<mode>_softfloat32"
7363   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7364         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7365   "! TARGET_POWERPC64 
7366    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
7367        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7368        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7369    && (gpc_reg_operand (operands[0], <MODE>mode)
7370        || gpc_reg_operand (operands[1], <MODE>mode))"
7371   "#"
7372   [(set_attr "type" "store,load,two,*,*,*")
7373    (set_attr "length" "8,8,8,8,12,16")])
7375 ; ld/std require word-aligned displacements -> 'Y' constraint.
7376 ; List Y->r and r->Y before r->r for reload.
7377 (define_insn "*mov<mode>_hardfloat64"
7378   [(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>")
7379         (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"))]
7380   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7381    && (gpc_reg_operand (operands[0], <MODE>mode)
7382        || gpc_reg_operand (operands[1], <MODE>mode))"
7383   "@
7384    stfd%U0%X0 %1,%0
7385    lfd%U1%X1 %0,%1
7386    fmr %0,%1
7387    lxsd %0,%1
7388    stxsd %1,%0
7389    lxsd%U1x %x0,%y1
7390    stxsd%U0x %x1,%y0
7391    xxlor %x0,%x1,%x1
7392    xxlxor %x0,%x0,%x0
7393    li %0,0
7394    std%U0%X0 %1,%0
7395    ld%U1%X1 %0,%1
7396    mr %0,%1
7397    mt%0 %1
7398    mf%1 %0
7399    nop
7400    mftgpr %0,%1
7401    mffgpr %0,%1
7402    mfvsrd %0,%x1
7403    mtvsrd %x0,%1"
7404   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7405    (set_attr "size" "64")
7406    (set_attr "length" "4")])
7408 (define_insn "*mov<mode>_softfloat64"
7409   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7410         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7411   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7412    && (gpc_reg_operand (operands[0], <MODE>mode)
7413        || gpc_reg_operand (operands[1], <MODE>mode))"
7414   "@
7415    std%U0%X0 %1,%0
7416    ld%U1%X1 %0,%1
7417    mr %0,%1
7418    mt%0 %1
7419    mf%1 %0
7420    #
7421    #
7422    #
7423    nop"
7424   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7425    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7427 (define_expand "mov<mode>"
7428   [(set (match_operand:FMOVE128 0 "general_operand" "")
7429         (match_operand:FMOVE128 1 "any_operand" ""))]
7430   ""
7431   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7433 ;; It's important to list Y->r and r->Y before r->r because otherwise
7434 ;; reload, given m->r, will try to pick r->r and reload it, which
7435 ;; doesn't make progress.
7437 ;; We can't split little endian direct moves of TDmode, because the words are
7438 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7439 ;; problematical.  Don't allow direct move for this case.
7441 (define_insn_and_split "*mov<mode>_64bit_dm"
7442   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7443         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7444   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7445    && FLOAT128_2REG_P (<MODE>mode)
7446    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7447    && (gpc_reg_operand (operands[0], <MODE>mode)
7448        || gpc_reg_operand (operands[1], <MODE>mode))"
7449   "#"
7450   "&& reload_completed"
7451   [(pc)]
7452 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7453   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7455 (define_insn_and_split "*movtd_64bit_nodm"
7456   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7457         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7458   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7459    && (gpc_reg_operand (operands[0], TDmode)
7460        || gpc_reg_operand (operands[1], TDmode))"
7461   "#"
7462   "&& reload_completed"
7463   [(pc)]
7464 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7465   [(set_attr "length" "8,8,8,12,12,8")])
7467 (define_insn_and_split "*mov<mode>_32bit"
7468   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7469         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7470   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7471    && (FLOAT128_2REG_P (<MODE>mode)
7472        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7473        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7474    && (gpc_reg_operand (operands[0], <MODE>mode)
7475        || gpc_reg_operand (operands[1], <MODE>mode))"
7476   "#"
7477   "&& reload_completed"
7478   [(pc)]
7479 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7480   [(set_attr "length" "8,8,8,8,20,20,16")])
7482 (define_insn_and_split "*mov<mode>_softfloat"
7483   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7484         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7485   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7486    && (gpc_reg_operand (operands[0], <MODE>mode)
7487        || gpc_reg_operand (operands[1], <MODE>mode))"
7488   "#"
7489   "&& reload_completed"
7490   [(pc)]
7491 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7492   [(set_attr "length" "20,20,16")])
7494 (define_expand "extenddf<mode>2"
7495   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7496         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7497   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7498    && TARGET_LONG_DOUBLE_128"
7500   if (FLOAT128_IEEE_P (<MODE>mode))
7501     rs6000_expand_float128_convert (operands[0], operands[1], false);
7502   else if (TARGET_E500_DOUBLE)
7503     {
7504       gcc_assert (<MODE>mode == TFmode);
7505       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7506     }
7507   else if (TARGET_VSX)
7508     {
7509       if (<MODE>mode == TFmode)
7510         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7511       else if (<MODE>mode == IFmode)
7512         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7513       else
7514         gcc_unreachable ();
7515     }
7516    else
7517     {
7518       rtx zero = gen_reg_rtx (DFmode);
7519       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7521       if (<MODE>mode == TFmode)
7522         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7523       else if (<MODE>mode == IFmode)
7524         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7525       else
7526         gcc_unreachable ();
7527     }
7528   DONE;
7531 ;; Allow memory operands for the source to be created by the combiner.
7532 (define_insn_and_split "extenddf<mode>2_fprs"
7533   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7534         (float_extend:IBM128
7535          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7536    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7537   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7538    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7539   "#"
7540   "&& reload_completed"
7541   [(set (match_dup 3) (match_dup 1))
7542    (set (match_dup 4) (match_dup 2))]
7544   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7545   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7547   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7548   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7551 (define_insn_and_split "extenddf<mode>2_vsx"
7552   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7553         (float_extend:IBM128
7554          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7555   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7556   "#"
7557   "&& reload_completed"
7558   [(set (match_dup 2) (match_dup 1))
7559    (set (match_dup 3) (match_dup 4))]
7561   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7562   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7564   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7565   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7566   operands[4] = CONST0_RTX (DFmode);
7569 (define_expand "extendsf<mode>2"
7570   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7571         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7572   "TARGET_HARD_FLOAT
7573    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7574    && TARGET_LONG_DOUBLE_128"
7576   if (FLOAT128_IEEE_P (<MODE>mode))
7577     rs6000_expand_float128_convert (operands[0], operands[1], false);
7578   else
7579     {
7580       rtx tmp = gen_reg_rtx (DFmode);
7581       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7582       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7583     }
7584   DONE;
7587 (define_expand "trunc<mode>df2"
7588   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7589         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7590   "TARGET_HARD_FLOAT
7591    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7592    && TARGET_LONG_DOUBLE_128"
7594   if (FLOAT128_IEEE_P (<MODE>mode))
7595     {
7596       rs6000_expand_float128_convert (operands[0], operands[1], false);
7597       DONE;
7598     }
7601 (define_insn_and_split "trunc<mode>df2_internal1"
7602   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7603         (float_truncate:DF
7604          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7605   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7606    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7607   "@
7608    #
7609    fmr %0,%1"
7610   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7611   [(const_int 0)]
7613   emit_note (NOTE_INSN_DELETED);
7614   DONE;
7616   [(set_attr "type" "fpsimple")])
7618 (define_insn "trunc<mode>df2_internal2"
7619   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7620         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7621   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7622    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7623   "fadd %0,%1,%L1"
7624   [(set_attr "type" "fp")
7625    (set_attr "fp_type" "fp_addsub_d")])
7627 (define_expand "trunc<mode>sf2"
7628   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7629         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7630   "TARGET_HARD_FLOAT
7631    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7632    && TARGET_LONG_DOUBLE_128"
7634   if (FLOAT128_IEEE_P (<MODE>mode))
7635     rs6000_expand_float128_convert (operands[0], operands[1], false);
7636   else if (TARGET_E500_DOUBLE)
7637     {
7638       gcc_assert (<MODE>mode == TFmode);
7639       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7640     }
7641   else if (<MODE>mode == TFmode)
7642     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7643   else if (<MODE>mode == IFmode)
7644     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7645   else
7646     gcc_unreachable ();
7647   DONE;
7650 (define_insn_and_split "trunc<mode>sf2_fprs"
7651   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7652         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7653    (clobber (match_scratch:DF 2 "=d"))]
7654   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7655    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7656   "#"
7657   "&& reload_completed"
7658   [(set (match_dup 2)
7659         (float_truncate:DF (match_dup 1)))
7660    (set (match_dup 0)
7661         (float_truncate:SF (match_dup 2)))]
7662   "")
7664 (define_expand "floatsi<mode>2"
7665   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7666         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7667   "TARGET_HARD_FLOAT
7668    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7669    && TARGET_LONG_DOUBLE_128"
7671   if (FLOAT128_IEEE_P (<MODE>mode))
7672     rs6000_expand_float128_convert (operands[0], operands[1], false);
7673   else
7674     {
7675       rtx tmp = gen_reg_rtx (DFmode);
7676       expand_float (tmp, operands[1], false);
7677       if (<MODE>mode == TFmode)
7678         emit_insn (gen_extenddftf2 (operands[0], tmp));
7679       else if (<MODE>mode == IFmode)
7680         emit_insn (gen_extenddfif2 (operands[0], tmp));
7681       else
7682         gcc_unreachable ();
7683     }
7684   DONE;
7687 ; fadd, but rounding towards zero.
7688 ; This is probably not the optimal code sequence.
7689 (define_insn "fix_trunc_helper<mode>"
7690   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7691         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7692                    UNSPEC_FIX_TRUNC_TF))
7693    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7694   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7695    && FLOAT128_IBM_P (<MODE>mode)"
7696   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7697   [(set_attr "type" "fp")
7698    (set_attr "length" "20")])
7700 (define_expand "fix_trunc<mode>si2"
7701   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7702         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7703   "TARGET_HARD_FLOAT
7704    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7706   if (FLOAT128_IEEE_P (<MODE>mode))
7707     rs6000_expand_float128_convert (operands[0], operands[1], false);
7708   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7709     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7710   else if (<MODE>mode == TFmode)
7711     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7712   else if (<MODE>mode == IFmode)
7713     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7714   else
7715     gcc_unreachable ();
7716   DONE;
7719 (define_expand "fix_trunc<mode>si2_fprs"
7720   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7721                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7722               (clobber (match_dup 2))
7723               (clobber (match_dup 3))
7724               (clobber (match_dup 4))
7725               (clobber (match_dup 5))])]
7726   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7728   operands[2] = gen_reg_rtx (DFmode);
7729   operands[3] = gen_reg_rtx (DFmode);
7730   operands[4] = gen_reg_rtx (DImode);
7731   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7734 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7735   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7736         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7737    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7738    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7739    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7740    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7741   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7742   "#"
7743   ""
7744   [(pc)]
7746   rtx lowword;
7747   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7748                                          operands[3]));
7750   gcc_assert (MEM_P (operands[5]));
7751   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7753   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7754   emit_move_insn (operands[5], operands[4]);
7755   emit_move_insn (operands[0], lowword);
7756   DONE;
7759 (define_expand "fix_trunc<mode>di2"
7760   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7761         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7762   "TARGET_FLOAT128_TYPE"
7764   rs6000_expand_float128_convert (operands[0], operands[1], false);
7765   DONE;
7768 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7769   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7770         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7771   "TARGET_FLOAT128_TYPE"
7773   rs6000_expand_float128_convert (operands[0], operands[1], true);
7774   DONE;
7777 (define_expand "floatdi<mode>2"
7778   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7779         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7780   "TARGET_FLOAT128_TYPE"
7782   rs6000_expand_float128_convert (operands[0], operands[1], false);
7783   DONE;
7786 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7787   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7788         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7789   "TARGET_FLOAT128_TYPE"
7791   rs6000_expand_float128_convert (operands[0], operands[1], true);
7792   DONE;
7795 (define_expand "neg<mode>2"
7796   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7797         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7798   "FLOAT128_IEEE_P (<MODE>mode)
7799    || (FLOAT128_IBM_P (<MODE>mode)
7800        && TARGET_HARD_FLOAT
7801        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7802   "
7804   if (FLOAT128_IEEE_P (<MODE>mode))
7805     {
7806       if (TARGET_FLOAT128_HW)
7807         {
7808           if (<MODE>mode == TFmode)
7809             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7810           else if (<MODE>mode == KFmode)
7811             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7812           else
7813             gcc_unreachable ();
7814         }
7815       else if (TARGET_FLOAT128_TYPE)
7816         {
7817           if (<MODE>mode == TFmode)
7818             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7819           else if (<MODE>mode == KFmode)
7820             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7821           else
7822             gcc_unreachable ();
7823         }
7824       else
7825         {
7826           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7827           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7828                                                 <MODE>mode, 1,
7829                                                 operands[1], <MODE>mode);
7831           if (target && !rtx_equal_p (target, operands[0]))
7832             emit_move_insn (operands[0], target);
7833         }
7834       DONE;
7835     }
7838 (define_insn "neg<mode>2_internal"
7839   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7840         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7841   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7842   "*
7844   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7845     return \"fneg %L0,%L1\;fneg %0,%1\";
7846   else
7847     return \"fneg %0,%1\;fneg %L0,%L1\";
7849   [(set_attr "type" "fpsimple")
7850    (set_attr "length" "8")])
7852 (define_expand "abs<mode>2"
7853   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7854         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7855   "FLOAT128_IEEE_P (<MODE>mode)
7856    || (FLOAT128_IBM_P (<MODE>mode)
7857        && TARGET_HARD_FLOAT
7858        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7859   "
7861   rtx label;
7863   if (FLOAT128_IEEE_P (<MODE>mode))
7864     {
7865       if (TARGET_FLOAT128_HW)
7866         {
7867           if (<MODE>mode == TFmode)
7868             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7869           else if (<MODE>mode == KFmode)
7870             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7871           else
7872             FAIL;
7873           DONE;
7874         }
7875       else if (TARGET_FLOAT128_TYPE)
7876         {
7877           if (<MODE>mode == TFmode)
7878             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7879           else if (<MODE>mode == KFmode)
7880             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7881           else
7882             FAIL;
7883           DONE;
7884         }
7885       else
7886         FAIL;
7887     }
7889   label = gen_label_rtx ();
7890   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7891     {
7892       if (flag_finite_math_only && !flag_trapping_math)
7893         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7894       else
7895         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7896     }
7897   else if (<MODE>mode == TFmode)
7898     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7899   else if (<MODE>mode == TFmode)
7900     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7901   else
7902     FAIL;
7903   emit_label (label);
7904   DONE;
7907 (define_expand "abs<mode>2_internal"
7908   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7909         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7910    (set (match_dup 3) (match_dup 5))
7911    (set (match_dup 5) (abs:DF (match_dup 5)))
7912    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7913    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7914                            (label_ref (match_operand 2 "" ""))
7915                            (pc)))
7916    (set (match_dup 6) (neg:DF (match_dup 6)))]
7917   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7918    && TARGET_LONG_DOUBLE_128"
7919   "
7921   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7922   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7923   operands[3] = gen_reg_rtx (DFmode);
7924   operands[4] = gen_reg_rtx (CCFPmode);
7925   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7926   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7930 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7931 ;; register
7933 (define_expand "ieee_128bit_negative_zero"
7934   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7935   "TARGET_FLOAT128_TYPE"
7937   rtvec v = rtvec_alloc (16);
7938   int i, high;
7940   for (i = 0; i < 16; i++)
7941     RTVEC_ELT (v, i) = const0_rtx;
7943   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7944   RTVEC_ELT (v, high) = GEN_INT (0x80);
7946   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7947   DONE;
7950 ;; IEEE 128-bit negate
7952 ;; We have 2 insns here for negate and absolute value.  The first uses
7953 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7954 ;; insns, and second insn after the first split pass loads up the bit to
7955 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7956 ;; neg/abs to create the constant just once.
7958 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7959   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7960         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7961    (clobber (match_scratch:V16QI 2 "=v"))]
7962   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7963   "#"
7964   "&& 1"
7965   [(parallel [(set (match_dup 0)
7966                    (neg:IEEE128 (match_dup 1)))
7967               (use (match_dup 2))])]
7969   if (GET_CODE (operands[2]) == SCRATCH)
7970     operands[2] = gen_reg_rtx (V16QImode);
7972   operands[3] = gen_reg_rtx (V16QImode);
7973   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7975   [(set_attr "length" "8")
7976    (set_attr "type" "vecsimple")])
7978 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7979   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7980         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7981    (use (match_operand:V16QI 2 "register_operand" "v"))]
7982   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7983   "xxlxor %x0,%x1,%x2"
7984   [(set_attr "type" "veclogical")])
7986 ;; IEEE 128-bit absolute value
7987 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7988   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7989         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7990    (clobber (match_scratch:V16QI 2 "=v"))]
7991   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7992   "#"
7993   "&& 1"
7994   [(parallel [(set (match_dup 0)
7995                    (abs:IEEE128 (match_dup 1)))
7996               (use (match_dup 2))])]
7998   if (GET_CODE (operands[2]) == SCRATCH)
7999     operands[2] = gen_reg_rtx (V16QImode);
8001   operands[3] = gen_reg_rtx (V16QImode);
8002   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8004   [(set_attr "length" "8")
8005    (set_attr "type" "vecsimple")])
8007 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8008   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8009         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8010    (use (match_operand:V16QI 2 "register_operand" "v"))]
8011   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8012   "xxlandc %x0,%x1,%x2"
8013   [(set_attr "type" "veclogical")])
8015 ;; IEEE 128-bit negative absolute value
8016 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8017   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8018         (neg:IEEE128
8019          (abs:IEEE128
8020           (match_operand:IEEE128 1 "register_operand" "wa"))))
8021    (clobber (match_scratch:V16QI 2 "=v"))]
8022   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8023    && FLOAT128_IEEE_P (<MODE>mode)"
8024   "#"
8025   "&& 1"
8026   [(parallel [(set (match_dup 0)
8027                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8028               (use (match_dup 2))])]
8030   if (GET_CODE (operands[2]) == SCRATCH)
8031     operands[2] = gen_reg_rtx (V16QImode);
8033   operands[3] = gen_reg_rtx (V16QImode);
8034   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8036   [(set_attr "length" "8")
8037    (set_attr "type" "vecsimple")])
8039 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8040   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8041         (neg:IEEE128
8042          (abs:IEEE128
8043           (match_operand:IEEE128 1 "register_operand" "wa"))))
8044    (use (match_operand:V16QI 2 "register_operand" "v"))]
8045   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8046   "xxlor %x0,%x1,%x2"
8047   [(set_attr "type" "veclogical")])
8049 ;; Float128 conversion functions.  These expand to library function calls.
8050 ;; We use expand to convert from IBM double double to IEEE 128-bit
8051 ;; and trunc for the opposite.
8052 (define_expand "extendiftf2"
8053   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8054         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8055   "TARGET_FLOAT128_TYPE"
8057   rs6000_expand_float128_convert (operands[0], operands[1], false);
8058   DONE;
8061 (define_expand "extendifkf2"
8062   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8063         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8064   "TARGET_FLOAT128_TYPE"
8066   rs6000_expand_float128_convert (operands[0], operands[1], false);
8067   DONE;
8070 (define_expand "extendtfkf2"
8071   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8072         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8073   "TARGET_FLOAT128_TYPE"
8075   rs6000_expand_float128_convert (operands[0], operands[1], false);
8076   DONE;
8079 (define_expand "trunciftf2"
8080   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8081         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8082   "TARGET_FLOAT128_TYPE"
8084   rs6000_expand_float128_convert (operands[0], operands[1], false);
8085   DONE;
8088 (define_expand "truncifkf2"
8089   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8090         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8091   "TARGET_FLOAT128_TYPE"
8093   rs6000_expand_float128_convert (operands[0], operands[1], false);
8094   DONE;
8097 (define_expand "trunckftf2"
8098   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8099         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8100   "TARGET_FLOAT128_TYPE"
8102   rs6000_expand_float128_convert (operands[0], operands[1], false);
8103   DONE;
8106 (define_expand "trunctfif2"
8107   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8108         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8109   "TARGET_FLOAT128_TYPE"
8111   rs6000_expand_float128_convert (operands[0], operands[1], false);
8112   DONE;
8116 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8117 ;; must have 3 arguments, and scratch register constraint must be a single
8118 ;; constraint.
8120 ;; Reload patterns to support gpr load/store with misaligned mem.
8121 ;; and multiple gpr load/store at offset >= 0xfffc
8122 (define_expand "reload_<mode>_store"
8123   [(parallel [(match_operand 0 "memory_operand" "=m")
8124               (match_operand 1 "gpc_reg_operand" "r")
8125               (match_operand:GPR 2 "register_operand" "=&b")])]
8126   ""
8128   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8129   DONE;
8132 (define_expand "reload_<mode>_load"
8133   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8134               (match_operand 1 "memory_operand" "m")
8135               (match_operand:GPR 2 "register_operand" "=b")])]
8136   ""
8138   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8139   DONE;
8143 ;; Reload patterns for various types using the vector registers.  We may need
8144 ;; an additional base register to convert the reg+offset addressing to reg+reg
8145 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8146 ;; index register for gpr registers.
8147 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8148   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8149               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8150               (match_operand:P 2 "register_operand" "=b")])]
8151   "<P:tptrsize>"
8153   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8154   DONE;
8157 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8158   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8159               (match_operand:RELOAD 1 "memory_operand" "m")
8160               (match_operand:P 2 "register_operand" "=b")])]
8161   "<P:tptrsize>"
8163   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8164   DONE;
8168 ;; Reload sometimes tries to move the address to a GPR, and can generate
8169 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8170 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8172 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8173   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8174         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8175                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8176                (const_int -16)))]
8177   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8178   "#"
8179   "&& reload_completed"
8180   [(set (match_dup 0)
8181         (plus:P (match_dup 1)
8182                 (match_dup 2)))
8183    (set (match_dup 0)
8184         (and:P (match_dup 0)
8185                (const_int -16)))])
8187 ;; Power8 merge instructions to allow direct move to/from floating point
8188 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8189 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8190 ;; value, since it is allocated in reload and not all of the flow information
8191 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8192 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8193 ;; schedule other instructions between the two instructions.
8195 (define_insn "p8_fmrgow_<mode>"
8196   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8197         (unspec:FMOVE64X [
8198                 (match_operand:DF 1 "register_operand" "d")
8199                 (match_operand:DF 2 "register_operand" "d")]
8200                          UNSPEC_P8V_FMRGOW))]
8201   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8202   "fmrgow %0,%1,%2"
8203   [(set_attr "type" "fpsimple")])
8205 (define_insn "p8_mtvsrwz"
8206   [(set (match_operand:DF 0 "register_operand" "=d")
8207         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8208                    UNSPEC_P8V_MTVSRWZ))]
8209   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8210   "mtvsrwz %x0,%1"
8211   [(set_attr "type" "mftgpr")])
8213 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8214   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8215         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8216                          UNSPEC_P8V_RELOAD_FROM_GPR))
8217    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8218   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8219   "#"
8220   "&& reload_completed"
8221   [(const_int 0)]
8223   rtx dest = operands[0];
8224   rtx src = operands[1];
8225   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8226   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8227   rtx gpr_hi_reg = gen_highpart (SImode, src);
8228   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8230   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8231   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8232   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8233   DONE;
8235   [(set_attr "length" "12")
8236    (set_attr "type" "three")])
8238 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8239 (define_insn "p8_mtvsrd_df"
8240   [(set (match_operand:DF 0 "register_operand" "=wa")
8241         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8242                    UNSPEC_P8V_MTVSRD))]
8243   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8244   "mtvsrd %x0,%1"
8245   [(set_attr "type" "mftgpr")])
8247 (define_insn "p8_xxpermdi_<mode>"
8248   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8249         (unspec:FMOVE128_GPR [
8250                 (match_operand:DF 1 "register_operand" "wa")
8251                 (match_operand:DF 2 "register_operand" "wa")]
8252                 UNSPEC_P8V_XXPERMDI))]
8253   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8254   "xxpermdi %x0,%x1,%x2,0"
8255   [(set_attr "type" "vecperm")])
8257 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8258   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8259         (unspec:FMOVE128_GPR
8260          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8261          UNSPEC_P8V_RELOAD_FROM_GPR))
8262    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8263   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8264   "#"
8265   "&& reload_completed"
8266   [(const_int 0)]
8268   rtx dest = operands[0];
8269   rtx src = operands[1];
8270   /* You might think that we could use op0 as one temp and a DF clobber
8271      as op2, but you'd be wrong.  Secondary reload move patterns don't
8272      check for overlap of the clobber and the destination.  */
8273   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8274   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8275   rtx gpr_hi_reg = gen_highpart (DImode, src);
8276   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8278   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8279   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8280   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8281   DONE;
8283   [(set_attr "length" "12")
8284    (set_attr "type" "three")])
8286 (define_split
8287   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8288         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8289   "reload_completed
8290    && (int_reg_operand (operands[0], <MODE>mode)
8291        || int_reg_operand (operands[1], <MODE>mode))
8292    && (!TARGET_DIRECT_MOVE_128
8293        || (!vsx_register_operand (operands[0], <MODE>mode)
8294            && !vsx_register_operand (operands[1], <MODE>mode)))"
8295   [(pc)]
8296 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8298 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8299 ;; type is stored internally as double precision in the VSX registers, we have
8300 ;; to convert it from the vector format.
8301 (define_insn "p8_mtvsrd_sf"
8302   [(set (match_operand:SF 0 "register_operand" "=wa")
8303         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8304                    UNSPEC_P8V_MTVSRD))]
8305   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8306   "mtvsrd %x0,%1"
8307   [(set_attr "type" "mftgpr")])
8309 (define_insn_and_split "reload_vsx_from_gprsf"
8310   [(set (match_operand:SF 0 "register_operand" "=wa")
8311         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8312                    UNSPEC_P8V_RELOAD_FROM_GPR))
8313    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8314   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8315   "#"
8316   "&& reload_completed"
8317   [(const_int 0)]
8319   rtx op0 = operands[0];
8320   rtx op1 = operands[1];
8321   rtx op2 = operands[2];
8322   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8324   /* Move SF value to upper 32-bits for xscvspdpn.  */
8325   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8326   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8327   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8328   DONE;
8330   [(set_attr "length" "8")
8331    (set_attr "type" "two")])
8333 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8334 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8335 ;; and then doing a move of that.
8336 (define_insn "p8_mfvsrd_3_<mode>"
8337   [(set (match_operand:DF 0 "register_operand" "=r")
8338         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8339                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8340   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8341   "mfvsrd %0,%x1"
8342   [(set_attr "type" "mftgpr")])
8344 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8345   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8346         (unspec:FMOVE128_GPR
8347          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8348          UNSPEC_P8V_RELOAD_FROM_VSX))
8349    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8350   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8351   "#"
8352   "&& reload_completed"
8353   [(const_int 0)]
8355   rtx dest = operands[0];
8356   rtx src = operands[1];
8357   rtx tmp = operands[2];
8358   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8359   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8361   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8362   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8363   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8364   DONE;
8366   [(set_attr "length" "12")
8367    (set_attr "type" "three")])
8369 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8370 ;; type is stored internally as double precision, we have to convert it to the
8371 ;; vector format.
8373 (define_insn_and_split "reload_gpr_from_vsxsf"
8374   [(set (match_operand:SF 0 "register_operand" "=r")
8375         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8376                    UNSPEC_P8V_RELOAD_FROM_VSX))
8377    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8378   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8379   "#"
8380   "&& reload_completed"
8381   [(const_int 0)]
8383   rtx op0 = operands[0];
8384   rtx op1 = operands[1];
8385   rtx op2 = operands[2];
8386   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8388   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8389   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8390   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8391   DONE;
8393   [(set_attr "length" "12")
8394    (set_attr "type" "three")])
8396 (define_insn "p8_mfvsrd_4_disf"
8397   [(set (match_operand:DI 0 "register_operand" "=r")
8398         (unspec:DI [(match_operand:V4SF 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")])
8405 ;; Next come the multi-word integer load and store and the load and store
8406 ;; multiple insns.
8408 ;; List r->r after r->Y, otherwise reload will try to reload a
8409 ;; non-offsettable address by using r->r which won't make progress.
8410 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8411 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8413 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8414 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8415 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8416 ;;        AVX const  
8418 (define_insn "*movdi_internal32"
8419   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8420          "=Y,        r,         r,         ^m,        ^d,         ^d,
8421           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8422           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8423           *wv")
8425         (match_operand:DI 1 "input_operand"
8426           "r,        Y,         r,         d,         m,          d,
8427            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8428            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8429            wB"))]
8431   "! TARGET_POWERPC64
8432    && (gpc_reg_operand (operands[0], DImode)
8433        || gpc_reg_operand (operands[1], DImode))"
8434   "@
8435    #
8436    #
8437    #
8438    stfd%U0%X0 %1,%0
8439    lfd%U1%X1 %0,%1
8440    fmr %0,%1
8441    #
8442    stxsd %1,%0
8443    stxsdx %x1,%y0
8444    lxsd %0,%1
8445    lxsdx %x0,%y1
8446    xxlor %x0,%x1,%x1
8447    xxspltib %x0,0
8448    xxspltib %x0,255
8449    vspltisw %0,%1
8450    xxlxor %x0,%x0,%x0
8451    xxlorc %x0,%x0,%x0
8452    #
8453    #"
8454   [(set_attr "type"
8455                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8456                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8457                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8458                 vecsimple")
8459    (set_attr "size" "64")])
8461 (define_split
8462   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8463         (match_operand:DI 1 "const_int_operand" ""))]
8464   "! TARGET_POWERPC64 && reload_completed
8465    && gpr_or_gpr_p (operands[0], operands[1])
8466    && !direct_move_p (operands[0], operands[1])"
8467   [(set (match_dup 2) (match_dup 4))
8468    (set (match_dup 3) (match_dup 1))]
8469   "
8471   HOST_WIDE_INT value = INTVAL (operands[1]);
8472   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8473                                        DImode);
8474   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8475                                        DImode);
8476   operands[4] = GEN_INT (value >> 32);
8477   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8480 (define_split
8481   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8482         (match_operand:DIFD 1 "input_operand" ""))]
8483   "reload_completed && !TARGET_POWERPC64
8484    && gpr_or_gpr_p (operands[0], operands[1])
8485    && !direct_move_p (operands[0], operands[1])"
8486   [(pc)]
8487 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8489 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8490 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8491 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8492 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8493 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8494 (define_insn "*movdi_internal64"
8495   [(set (match_operand:DI 0 "nonimmediate_operand"
8496                "=Y,        r,         r,         r,         r,          r,
8497                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8498                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8499                 *wi,       *wv,       *wv,       r,         *h,         *h,
8500                 ?*r,       ?*wg,      ?*r,       ?*wj")
8502         (match_operand:DI 1 "input_operand"
8503                 "r,        Y,         r,         I,         L,          nF,
8504                  d,        m,         d,         wb,        wv,         wY,
8505                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8506                  wM,       wS,        wB,        *h,        r,          0,
8507                  wg,       r,         wj,        r"))]
8509   "TARGET_POWERPC64
8510    && (gpc_reg_operand (operands[0], DImode)
8511        || gpc_reg_operand (operands[1], DImode))"
8512   "@
8513    std%U0%X0 %1,%0
8514    ld%U1%X1 %0,%1
8515    mr %0,%1
8516    li %0,%1
8517    lis %0,%v1
8518    #
8519    stfd%U0%X0 %1,%0
8520    lfd%U1%X1 %0,%1
8521    fmr %0,%1
8522    stxsd %1,%0
8523    stxsdx %x1,%y0
8524    lxsd %0,%1
8525    lxsdx %x0,%y1
8526    xxlor %x0,%x1,%x1
8527    xxspltib %x0,0
8528    xxspltib %x0,255
8529    #
8530    xxlxor %x0,%x0,%x0
8531    xxlorc %x0,%x0,%x0
8532    #
8533    #
8534    mf%1 %0
8535    mt%0 %1
8536    nop
8537    mftgpr %0,%1
8538    mffgpr %0,%1
8539    mfvsrd %0,%x1
8540    mtvsrd %x0,%1"
8541   [(set_attr "type"
8542                "store,      load,       *,         *,         *,         *,
8543                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8544                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8545                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8546                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8548    (set_attr "size" "64")
8549    (set_attr "length"
8550                "4,         4,         4,         4,         4,          20,
8551                 4,         4,         4,         4,         4,          4,
8552                 4,         4,         4,         4,         4,          8,
8553                 8,         4,         4,         4,         4,          4,
8554                 4,         4,         4,         4")])
8556 ; Some DImode loads are best done as a load of -1 followed by a mask
8557 ; instruction.
8558 (define_split
8559   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8560         (match_operand:DI 1 "const_int_operand"))]
8561   "TARGET_POWERPC64
8562    && num_insns_constant (operands[1], DImode) > 1
8563    && rs6000_is_valid_and_mask (operands[1], DImode)"
8564   [(set (match_dup 0)
8565         (const_int -1))
8566    (set (match_dup 0)
8567         (and:DI (match_dup 0)
8568                 (match_dup 1)))]
8569   "")
8571 ;; Split a load of a large constant into the appropriate five-instruction
8572 ;; sequence.  Handle anything in a constant number of insns.
8573 ;; When non-easy constants can go in the TOC, this should use
8574 ;; easy_fp_constant predicate.
8575 (define_split
8576   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8577         (match_operand:DI 1 "const_int_operand" ""))]
8578   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8579   [(set (match_dup 0) (match_dup 2))
8580    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8581   "
8583   if (rs6000_emit_set_const (operands[0], operands[1]))
8584     DONE;
8585   else
8586     FAIL;
8589 (define_split
8590   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8591         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8592   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8593   [(set (match_dup 0) (match_dup 2))
8594    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8595   "
8597   if (rs6000_emit_set_const (operands[0], operands[1]))
8598     DONE;
8599   else
8600     FAIL;
8603 (define_split
8604   [(set (match_operand:DI 0 "altivec_register_operand" "")
8605         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8606   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8607   [(const_int 0)]
8609   rtx op0 = operands[0];
8610   rtx op1 = operands[1];
8611   int r = REGNO (op0);
8612   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8614   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8615   if (op1 != const0_rtx && op1 != constm1_rtx)
8616     {
8617       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8618       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8619     }
8620   DONE;
8623 ;; Split integer constants that can be loaded with XXSPLTIB and a
8624 ;; sign extend operation.
8625 (define_split
8626   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8627         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8628   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8629   [(const_int 0)]
8631   rtx op0 = operands[0];
8632   rtx op1 = operands[1];
8633   int r = REGNO (op0);
8634   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8636   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8637   if (<MODE>mode == DImode)
8638     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8639   else if (<MODE>mode == SImode)
8640     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8641   else if (<MODE>mode == HImode)
8642     {
8643       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8644       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8645     }
8646   DONE;
8650 ;; TImode/PTImode is similar, except that we usually want to compute the
8651 ;; address into a register and use lsi/stsi (the exception is during reload).
8653 (define_insn "*mov<mode>_string"
8654   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8655         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8656   "! TARGET_POWERPC64
8657    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8658    && (gpc_reg_operand (operands[0], <MODE>mode)
8659        || gpc_reg_operand (operands[1], <MODE>mode))"
8660   "*
8662   switch (which_alternative)
8663     {
8664     default:
8665       gcc_unreachable ();
8666     case 0:
8667       if (TARGET_STRING)
8668         return \"stswi %1,%P0,16\";
8669       /* FALLTHRU */
8670     case 1:
8671       return \"#\";
8672     case 2:
8673       /* If the address is not used in the output, we can use lsi.  Otherwise,
8674          fall through to generating four loads.  */
8675       if (TARGET_STRING
8676           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8677         return \"lswi %0,%P1,16\";
8678       /* fall through */
8679     case 3:
8680     case 4:
8681     case 5:
8682       return \"#\";
8683     }
8685   [(set_attr "type" "store,store,load,load,*,*")
8686    (set_attr "update" "yes")
8687    (set_attr "indexed" "yes")
8688    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8689                                           (const_string "always")
8690                                           (const_string "conditional")))])
8692 (define_insn "*mov<mode>_ppc64"
8693   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8694         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8695   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8696    && (gpc_reg_operand (operands[0], <MODE>mode)
8697        || gpc_reg_operand (operands[1], <MODE>mode)))"
8699   return rs6000_output_move_128bit (operands);
8701   [(set_attr "type" "store,store,load,load,*,*")
8702    (set_attr "length" "8")])
8704 (define_split
8705   [(set (match_operand:TI2 0 "int_reg_operand" "")
8706         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8707   "TARGET_POWERPC64
8708    && (VECTOR_MEM_NONE_P (<MODE>mode)
8709        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8710   [(set (match_dup 2) (match_dup 4))
8711    (set (match_dup 3) (match_dup 5))]
8712   "
8714   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8715                                        <MODE>mode);
8716   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8717                                        <MODE>mode);
8718   if (CONST_WIDE_INT_P (operands[1]))
8719     {
8720       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8721       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8722     }
8723   else if (CONST_INT_P (operands[1]))
8724     {
8725       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8726       operands[5] = operands[1];
8727     }
8728   else
8729     FAIL;
8732 (define_split
8733   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8734         (match_operand:TI2 1 "input_operand" ""))]
8735   "reload_completed
8736    && gpr_or_gpr_p (operands[0], operands[1])
8737    && !direct_move_p (operands[0], operands[1])
8738    && !quad_load_store_p (operands[0], operands[1])"
8739   [(pc)]
8740 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8742 (define_expand "load_multiple"
8743   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8744                           (match_operand:SI 1 "" ""))
8745                      (use (match_operand:SI 2 "" ""))])]
8746   "TARGET_STRING && !TARGET_POWERPC64"
8747   "
8749   int regno;
8750   int count;
8751   rtx op1;
8752   int i;
8754   /* Support only loading a constant number of fixed-point registers from
8755      memory and only bother with this if more than two; the machine
8756      doesn't support more than eight.  */
8757   if (GET_CODE (operands[2]) != CONST_INT
8758       || INTVAL (operands[2]) <= 2
8759       || INTVAL (operands[2]) > 8
8760       || GET_CODE (operands[1]) != MEM
8761       || GET_CODE (operands[0]) != REG
8762       || REGNO (operands[0]) >= 32)
8763     FAIL;
8765   count = INTVAL (operands[2]);
8766   regno = REGNO (operands[0]);
8768   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8769   op1 = replace_equiv_address (operands[1],
8770                                force_reg (SImode, XEXP (operands[1], 0)));
8772   for (i = 0; i < count; i++)
8773     XVECEXP (operands[3], 0, i)
8774       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8775                      adjust_address_nv (op1, SImode, i * 4));
8778 (define_insn "*ldmsi8"
8779   [(match_parallel 0 "load_multiple_operation"
8780     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8781           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8782      (set (match_operand:SI 3 "gpc_reg_operand" "")
8783           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8784      (set (match_operand:SI 4 "gpc_reg_operand" "")
8785           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8786      (set (match_operand:SI 5 "gpc_reg_operand" "")
8787           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8788      (set (match_operand:SI 6 "gpc_reg_operand" "")
8789           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8790      (set (match_operand:SI 7 "gpc_reg_operand" "")
8791           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8792      (set (match_operand:SI 8 "gpc_reg_operand" "")
8793           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8794      (set (match_operand:SI 9 "gpc_reg_operand" "")
8795           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8796   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8797   "*
8798 { return rs6000_output_load_multiple (operands); }"
8799   [(set_attr "type" "load")
8800    (set_attr "update" "yes")
8801    (set_attr "indexed" "yes")
8802    (set_attr "length" "32")])
8804 (define_insn "*ldmsi7"
8805   [(match_parallel 0 "load_multiple_operation"
8806     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8807           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8808      (set (match_operand:SI 3 "gpc_reg_operand" "")
8809           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8810      (set (match_operand:SI 4 "gpc_reg_operand" "")
8811           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8812      (set (match_operand:SI 5 "gpc_reg_operand" "")
8813           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8814      (set (match_operand:SI 6 "gpc_reg_operand" "")
8815           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8816      (set (match_operand:SI 7 "gpc_reg_operand" "")
8817           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8818      (set (match_operand:SI 8 "gpc_reg_operand" "")
8819           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8820   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8821   "*
8822 { return rs6000_output_load_multiple (operands); }"
8823   [(set_attr "type" "load")
8824    (set_attr "update" "yes")
8825    (set_attr "indexed" "yes")
8826    (set_attr "length" "32")])
8828 (define_insn "*ldmsi6"
8829   [(match_parallel 0 "load_multiple_operation"
8830     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8831           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8832      (set (match_operand:SI 3 "gpc_reg_operand" "")
8833           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8834      (set (match_operand:SI 4 "gpc_reg_operand" "")
8835           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8836      (set (match_operand:SI 5 "gpc_reg_operand" "")
8837           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8838      (set (match_operand:SI 6 "gpc_reg_operand" "")
8839           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8840      (set (match_operand:SI 7 "gpc_reg_operand" "")
8841           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8842   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8843   "*
8844 { return rs6000_output_load_multiple (operands); }"
8845   [(set_attr "type" "load")
8846    (set_attr "update" "yes")
8847    (set_attr "indexed" "yes")
8848    (set_attr "length" "32")])
8850 (define_insn "*ldmsi5"
8851   [(match_parallel 0 "load_multiple_operation"
8852     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8853           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8854      (set (match_operand:SI 3 "gpc_reg_operand" "")
8855           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8856      (set (match_operand:SI 4 "gpc_reg_operand" "")
8857           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8858      (set (match_operand:SI 5 "gpc_reg_operand" "")
8859           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8860      (set (match_operand:SI 6 "gpc_reg_operand" "")
8861           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8862   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8863   "*
8864 { return rs6000_output_load_multiple (operands); }"
8865   [(set_attr "type" "load")
8866    (set_attr "update" "yes")
8867    (set_attr "indexed" "yes")
8868    (set_attr "length" "32")])
8870 (define_insn "*ldmsi4"
8871   [(match_parallel 0 "load_multiple_operation"
8872     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8873           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8874      (set (match_operand:SI 3 "gpc_reg_operand" "")
8875           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8876      (set (match_operand:SI 4 "gpc_reg_operand" "")
8877           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8878      (set (match_operand:SI 5 "gpc_reg_operand" "")
8879           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8880   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
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 "*ldmsi3"
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   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8897   "*
8898 { return rs6000_output_load_multiple (operands); }"
8899   [(set_attr "type" "load")
8900    (set_attr "update" "yes")
8901    (set_attr "indexed" "yes")
8902    (set_attr "length" "32")])
8904 (define_expand "store_multiple"
8905   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8906                           (match_operand:SI 1 "" ""))
8907                      (clobber (scratch:SI))
8908                      (use (match_operand:SI 2 "" ""))])]
8909   "TARGET_STRING && !TARGET_POWERPC64"
8910   "
8912   int regno;
8913   int count;
8914   rtx to;
8915   rtx op0;
8916   int i;
8918   /* Support only storing a constant number of fixed-point registers to
8919      memory and only bother with this if more than two; the machine
8920      doesn't support more than eight.  */
8921   if (GET_CODE (operands[2]) != CONST_INT
8922       || INTVAL (operands[2]) <= 2
8923       || INTVAL (operands[2]) > 8
8924       || GET_CODE (operands[0]) != MEM
8925       || GET_CODE (operands[1]) != REG
8926       || REGNO (operands[1]) >= 32)
8927     FAIL;
8929   count = INTVAL (operands[2]);
8930   regno = REGNO (operands[1]);
8932   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8933   to = force_reg (SImode, XEXP (operands[0], 0));
8934   op0 = replace_equiv_address (operands[0], to);
8936   XVECEXP (operands[3], 0, 0)
8937     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8938   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8939                                                  gen_rtx_SCRATCH (SImode));
8941   for (i = 1; i < count; i++)
8942     XVECEXP (operands[3], 0, i + 1)
8943       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8944                      gen_rtx_REG (SImode, regno + i));
8947 (define_insn "*stmsi8"
8948   [(match_parallel 0 "store_multiple_operation"
8949     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8950           (match_operand:SI 2 "gpc_reg_operand" "r"))
8951      (clobber (match_scratch:SI 3 "=X"))
8952      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8953           (match_operand:SI 4 "gpc_reg_operand" "r"))
8954      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8955           (match_operand:SI 5 "gpc_reg_operand" "r"))
8956      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8957           (match_operand:SI 6 "gpc_reg_operand" "r"))
8958      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8959           (match_operand:SI 7 "gpc_reg_operand" "r"))
8960      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8961           (match_operand:SI 8 "gpc_reg_operand" "r"))
8962      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8963           (match_operand:SI 9 "gpc_reg_operand" "r"))
8964      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8965           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8966   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8967   "stswi %2,%1,%O0"
8968   [(set_attr "type" "store")
8969    (set_attr "update" "yes")
8970    (set_attr "indexed" "yes")
8971    (set_attr "cell_micro" "always")])
8973 (define_insn "*stmsi7"
8974   [(match_parallel 0 "store_multiple_operation"
8975     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8976           (match_operand:SI 2 "gpc_reg_operand" "r"))
8977      (clobber (match_scratch:SI 3 "=X"))
8978      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8979           (match_operand:SI 4 "gpc_reg_operand" "r"))
8980      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8981           (match_operand:SI 5 "gpc_reg_operand" "r"))
8982      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8983           (match_operand:SI 6 "gpc_reg_operand" "r"))
8984      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8985           (match_operand:SI 7 "gpc_reg_operand" "r"))
8986      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8987           (match_operand:SI 8 "gpc_reg_operand" "r"))
8988      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8989           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8990   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8991   "stswi %2,%1,%O0"
8992   [(set_attr "type" "store")
8993    (set_attr "update" "yes")
8994    (set_attr "indexed" "yes")
8995    (set_attr "cell_micro" "always")])
8997 (define_insn "*stmsi6"
8998   [(match_parallel 0 "store_multiple_operation"
8999     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9000           (match_operand:SI 2 "gpc_reg_operand" "r"))
9001      (clobber (match_scratch:SI 3 "=X"))
9002      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9003           (match_operand:SI 4 "gpc_reg_operand" "r"))
9004      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9005           (match_operand:SI 5 "gpc_reg_operand" "r"))
9006      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9007           (match_operand:SI 6 "gpc_reg_operand" "r"))
9008      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9009           (match_operand:SI 7 "gpc_reg_operand" "r"))
9010      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9011           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9012   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9013   "stswi %2,%1,%O0"
9014   [(set_attr "type" "store")
9015    (set_attr "update" "yes")
9016    (set_attr "indexed" "yes")
9017    (set_attr "cell_micro" "always")])
9019 (define_insn "*stmsi5"
9020   [(match_parallel 0 "store_multiple_operation"
9021     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9022           (match_operand:SI 2 "gpc_reg_operand" "r"))
9023      (clobber (match_scratch:SI 3 "=X"))
9024      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9025           (match_operand:SI 4 "gpc_reg_operand" "r"))
9026      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9027           (match_operand:SI 5 "gpc_reg_operand" "r"))
9028      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9029           (match_operand:SI 6 "gpc_reg_operand" "r"))
9030      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9031           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9032   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9033   "stswi %2,%1,%O0"
9034   [(set_attr "type" "store")
9035    (set_attr "update" "yes")
9036    (set_attr "indexed" "yes")
9037    (set_attr "cell_micro" "always")])
9039 (define_insn "*stmsi4"
9040   [(match_parallel 0 "store_multiple_operation"
9041     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9042           (match_operand:SI 2 "gpc_reg_operand" "r"))
9043      (clobber (match_scratch:SI 3 "=X"))
9044      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9045           (match_operand:SI 4 "gpc_reg_operand" "r"))
9046      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9047           (match_operand:SI 5 "gpc_reg_operand" "r"))
9048      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9049           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9050   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
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 "*stmsi3"
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   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9067   "stswi %2,%1,%O0"
9068   [(set_attr "type" "store")
9069    (set_attr "update" "yes")
9070    (set_attr "indexed" "yes")
9071    (set_attr "cell_micro" "always")])
9073 (define_expand "setmemsi"
9074   [(parallel [(set (match_operand:BLK 0 "" "")
9075                    (match_operand 2 "const_int_operand" ""))
9076               (use (match_operand:SI 1 "" ""))
9077               (use (match_operand:SI 3 "" ""))])]
9078   ""
9079   "
9081   /* If value to set is not zero, use the library routine.  */
9082   if (operands[2] != const0_rtx)
9083     FAIL;
9085   if (expand_block_clear (operands))
9086     DONE;
9087   else
9088     FAIL;
9091 ;; String compare N insn.
9092 ;; Argument 0 is the target (result)
9093 ;; Argument 1 is the destination
9094 ;; Argument 2 is the source
9095 ;; Argument 3 is the length
9096 ;; Argument 4 is the alignment
9098 (define_expand "cmpstrnsi"
9099   [(parallel [(set (match_operand:SI 0)
9100                (compare:SI (match_operand:BLK 1)
9101                            (match_operand:BLK 2)))
9102               (use (match_operand:SI 3))
9103               (use (match_operand:SI 4))])]
9104   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9106   if (expand_strn_compare (operands))
9107     DONE;
9108   else  
9109     FAIL;
9112 ;; Block compare insn.
9113 ;; Argument 0 is the target (result)
9114 ;; Argument 1 is the destination
9115 ;; Argument 2 is the source
9116 ;; Argument 3 is the length
9117 ;; Argument 4 is the alignment
9119 (define_expand "cmpmemsi"
9120   [(parallel [(set (match_operand:SI 0)
9121                (compare:SI (match_operand:BLK 1)
9122                            (match_operand:BLK 2)))
9123               (use (match_operand:SI 3))
9124               (use (match_operand:SI 4))])]
9125   ""
9127   if (expand_block_compare (operands))
9128     DONE;
9129   else  
9130     FAIL;
9133 ;; String/block move insn.
9134 ;; Argument 0 is the destination
9135 ;; Argument 1 is the source
9136 ;; Argument 2 is the length
9137 ;; Argument 3 is the alignment
9139 (define_expand "movmemsi"
9140   [(parallel [(set (match_operand:BLK 0 "" "")
9141                    (match_operand:BLK 1 "" ""))
9142               (use (match_operand:SI 2 "" ""))
9143               (use (match_operand:SI 3 "" ""))])]
9144   ""
9145   "
9147   if (expand_block_move (operands))
9148     DONE;
9149   else
9150     FAIL;
9153 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9154 ;; register allocator doesn't have a clue about allocating 8 word registers.
9155 ;; rD/rS = r5 is preferred, efficient form.
9156 (define_expand "movmemsi_8reg"
9157   [(parallel [(set (match_operand 0 "" "")
9158                    (match_operand 1 "" ""))
9159               (use (match_operand 2 "" ""))
9160               (use (match_operand 3 "" ""))
9161               (clobber (reg:SI  5))
9162               (clobber (reg:SI  6))
9163               (clobber (reg:SI  7))
9164               (clobber (reg:SI  8))
9165               (clobber (reg:SI  9))
9166               (clobber (reg:SI 10))
9167               (clobber (reg:SI 11))
9168               (clobber (reg:SI 12))
9169               (clobber (match_scratch:SI 4 ""))])]
9170   "TARGET_STRING"
9171   "")
9173 (define_insn ""
9174   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9175         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9176    (use (match_operand:SI 2 "immediate_operand" "i"))
9177    (use (match_operand:SI 3 "immediate_operand" "i"))
9178    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9179    (clobber (reg:SI  6))
9180    (clobber (reg:SI  7))
9181    (clobber (reg:SI  8))
9182    (clobber (reg:SI  9))
9183    (clobber (reg:SI 10))
9184    (clobber (reg:SI 11))
9185    (clobber (reg:SI 12))
9186    (clobber (match_scratch:SI 5 "=X"))]
9187   "TARGET_STRING
9188    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9189        || INTVAL (operands[2]) == 0)
9190    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9191    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9192    && REGNO (operands[4]) == 5"
9193   "lswi %4,%1,%2\;stswi %4,%0,%2"
9194   [(set_attr "type" "store")
9195    (set_attr "update" "yes")
9196    (set_attr "indexed" "yes")
9197    (set_attr "cell_micro" "always")
9198    (set_attr "length" "8")])
9200 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9201 ;; register allocator doesn't have a clue about allocating 6 word registers.
9202 ;; rD/rS = r5 is preferred, efficient form.
9203 (define_expand "movmemsi_6reg"
9204   [(parallel [(set (match_operand 0 "" "")
9205                    (match_operand 1 "" ""))
9206               (use (match_operand 2 "" ""))
9207               (use (match_operand 3 "" ""))
9208               (clobber (reg:SI  5))
9209               (clobber (reg:SI  6))
9210               (clobber (reg:SI  7))
9211               (clobber (reg:SI  8))
9212               (clobber (reg:SI  9))
9213               (clobber (reg:SI 10))
9214               (clobber (match_scratch:SI 4 ""))])]
9215   "TARGET_STRING"
9216   "")
9218 (define_insn ""
9219   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9220         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9221    (use (match_operand:SI 2 "immediate_operand" "i"))
9222    (use (match_operand:SI 3 "immediate_operand" "i"))
9223    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9224    (clobber (reg:SI  6))
9225    (clobber (reg:SI  7))
9226    (clobber (reg:SI  8))
9227    (clobber (reg:SI  9))
9228    (clobber (reg:SI 10))
9229    (clobber (match_scratch:SI 5 "=X"))]
9230   "TARGET_STRING
9231    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9232    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9233    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9234    && REGNO (operands[4]) == 5"
9235   "lswi %4,%1,%2\;stswi %4,%0,%2"
9236   [(set_attr "type" "store")
9237    (set_attr "update" "yes")
9238    (set_attr "indexed" "yes")
9239    (set_attr "cell_micro" "always")
9240    (set_attr "length" "8")])
9242 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9243 ;; problems with TImode.
9244 ;; rD/rS = r5 is preferred, efficient form.
9245 (define_expand "movmemsi_4reg"
9246   [(parallel [(set (match_operand 0 "" "")
9247                    (match_operand 1 "" ""))
9248               (use (match_operand 2 "" ""))
9249               (use (match_operand 3 "" ""))
9250               (clobber (reg:SI 5))
9251               (clobber (reg:SI 6))
9252               (clobber (reg:SI 7))
9253               (clobber (reg:SI 8))
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 (match_scratch:SI 5 "=X"))]
9268   "TARGET_STRING
9269    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9270    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9271    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9272    && REGNO (operands[4]) == 5"
9273   "lswi %4,%1,%2\;stswi %4,%0,%2"
9274   [(set_attr "type" "store")
9275    (set_attr "update" "yes")
9276    (set_attr "indexed" "yes")
9277    (set_attr "cell_micro" "always")
9278    (set_attr "length" "8")])
9280 ;; Move up to 8 bytes at a time.
9281 (define_expand "movmemsi_2reg"
9282   [(parallel [(set (match_operand 0 "" "")
9283                    (match_operand 1 "" ""))
9284               (use (match_operand 2 "" ""))
9285               (use (match_operand 3 "" ""))
9286               (clobber (match_scratch:DI 4 ""))
9287               (clobber (match_scratch:SI 5 ""))])]
9288   "TARGET_STRING && ! TARGET_POWERPC64"
9289   "")
9291 (define_insn ""
9292   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9293         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9294    (use (match_operand:SI 2 "immediate_operand" "i"))
9295    (use (match_operand:SI 3 "immediate_operand" "i"))
9296    (clobber (match_scratch:DI 4 "=&r"))
9297    (clobber (match_scratch:SI 5 "=X"))]
9298   "TARGET_STRING && ! TARGET_POWERPC64
9299    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9300   "lswi %4,%1,%2\;stswi %4,%0,%2"
9301   [(set_attr "type" "store")
9302    (set_attr "update" "yes")
9303    (set_attr "indexed" "yes")
9304    (set_attr "cell_micro" "always")
9305    (set_attr "length" "8")])
9307 ;; Move up to 4 bytes at a time.
9308 (define_expand "movmemsi_1reg"
9309   [(parallel [(set (match_operand 0 "" "")
9310                    (match_operand 1 "" ""))
9311               (use (match_operand 2 "" ""))
9312               (use (match_operand 3 "" ""))
9313               (clobber (match_scratch:SI 4 ""))
9314               (clobber (match_scratch:SI 5 ""))])]
9315   "TARGET_STRING"
9316   "")
9318 (define_insn ""
9319   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9320         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9321    (use (match_operand:SI 2 "immediate_operand" "i"))
9322    (use (match_operand:SI 3 "immediate_operand" "i"))
9323    (clobber (match_scratch:SI 4 "=&r"))
9324    (clobber (match_scratch:SI 5 "=X"))]
9325   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9326   "lswi %4,%1,%2\;stswi %4,%0,%2"
9327   [(set_attr "type" "store")
9328    (set_attr "update" "yes")
9329    (set_attr "indexed" "yes")
9330    (set_attr "cell_micro" "always")
9331    (set_attr "length" "8")])
9333 ;; Define insns that do load or store with update.  Some of these we can
9334 ;; get by using pre-decrement or pre-increment, but the hardware can also
9335 ;; do cases where the increment is not the size of the object.
9337 ;; In all these cases, we use operands 0 and 1 for the register being
9338 ;; incremented because those are the operands that local-alloc will
9339 ;; tie and these are the pair most likely to be tieable (and the ones
9340 ;; that will benefit the most).
9342 (define_insn "*movdi_update1"
9343   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9344         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9345                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9346    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9347         (plus:DI (match_dup 1) (match_dup 2)))]
9348   "TARGET_POWERPC64 && TARGET_UPDATE
9349    && (!avoiding_indexed_address_p (DImode)
9350        || !gpc_reg_operand (operands[2], DImode))"
9351   "@
9352    ldux %3,%0,%2
9353    ldu %3,%2(%0)"
9354   [(set_attr "type" "load")
9355    (set_attr "update" "yes")
9356    (set_attr "indexed" "yes,no")])
9358 (define_insn "movdi_<mode>_update"
9359   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9360                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9361         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9362    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9363         (plus:P (match_dup 1) (match_dup 2)))]
9364   "TARGET_POWERPC64 && TARGET_UPDATE
9365    && (!avoiding_indexed_address_p (Pmode)
9366        || !gpc_reg_operand (operands[2], Pmode)
9367        || (REG_P (operands[0])
9368            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9369   "@
9370    stdux %3,%0,%2
9371    stdu %3,%2(%0)"
9372   [(set_attr "type" "store")
9373    (set_attr "update" "yes")
9374    (set_attr "indexed" "yes,no")])
9376 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9377 ;; needed for stack allocation, even if the user passes -mno-update.
9378 (define_insn "movdi_<mode>_update_stack"
9379   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9380                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9381         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9382    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9383         (plus:P (match_dup 1) (match_dup 2)))]
9384   "TARGET_POWERPC64"
9385   "@
9386    stdux %3,%0,%2
9387    stdu %3,%2(%0)"
9388   [(set_attr "type" "store")
9389    (set_attr "update" "yes")
9390    (set_attr "indexed" "yes,no")])
9392 (define_insn "*movsi_update1"
9393   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9394         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9395                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9396    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9397         (plus:SI (match_dup 1) (match_dup 2)))]
9398   "TARGET_UPDATE
9399    && (!avoiding_indexed_address_p (SImode)
9400        || !gpc_reg_operand (operands[2], SImode))"
9401   "@
9402    lwzux %3,%0,%2
9403    lwzu %3,%2(%0)"
9404   [(set_attr "type" "load")
9405    (set_attr "update" "yes")
9406    (set_attr "indexed" "yes,no")])
9408 (define_insn "*movsi_update2"
9409   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9410         (sign_extend:DI
9411          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9412                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9413    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9414         (plus:DI (match_dup 1) (match_dup 2)))]
9415   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9416    && !avoiding_indexed_address_p (DImode)"
9417   "lwaux %3,%0,%2"
9418   [(set_attr "type" "load")
9419    (set_attr "sign_extend" "yes")
9420    (set_attr "update" "yes")
9421    (set_attr "indexed" "yes")])
9423 (define_insn "movsi_update"
9424   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9425                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9426         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9427    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9428         (plus:SI (match_dup 1) (match_dup 2)))]
9429   "TARGET_UPDATE
9430    && (!avoiding_indexed_address_p (SImode)
9431        || !gpc_reg_operand (operands[2], SImode)
9432        || (REG_P (operands[0])
9433            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9434   "@
9435    stwux %3,%0,%2
9436    stwu %3,%2(%0)"
9437   [(set_attr "type" "store")
9438    (set_attr "update" "yes")
9439    (set_attr "indexed" "yes,no")])
9441 ;; This is an unconditional pattern; needed for stack allocation, even
9442 ;; if the user passes -mno-update.
9443 (define_insn "movsi_update_stack"
9444   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9445                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9446         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9447    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9448         (plus:SI (match_dup 1) (match_dup 2)))]
9449   ""
9450   "@
9451    stwux %3,%0,%2
9452    stwu %3,%2(%0)"
9453   [(set_attr "type" "store")
9454    (set_attr "update" "yes")
9455    (set_attr "indexed" "yes,no")])
9457 (define_insn "*movhi_update1"
9458   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9459         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9460                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9461    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9462         (plus:SI (match_dup 1) (match_dup 2)))]
9463   "TARGET_UPDATE
9464    && (!avoiding_indexed_address_p (SImode)
9465        || !gpc_reg_operand (operands[2], SImode))"
9466   "@
9467    lhzux %3,%0,%2
9468    lhzu %3,%2(%0)"
9469   [(set_attr "type" "load")
9470    (set_attr "update" "yes")
9471    (set_attr "indexed" "yes,no")])
9473 (define_insn "*movhi_update2"
9474   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9475         (zero_extend:SI
9476          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9477                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9478    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9479         (plus:SI (match_dup 1) (match_dup 2)))]
9480   "TARGET_UPDATE
9481    && (!avoiding_indexed_address_p (SImode)
9482        || !gpc_reg_operand (operands[2], SImode))"
9483   "@
9484    lhzux %3,%0,%2
9485    lhzu %3,%2(%0)"
9486   [(set_attr "type" "load")
9487    (set_attr "update" "yes")
9488    (set_attr "indexed" "yes,no")])
9490 (define_insn "*movhi_update3"
9491   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9492         (sign_extend:SI
9493          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9494                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9495    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9496         (plus:SI (match_dup 1) (match_dup 2)))]
9497   "TARGET_UPDATE && rs6000_gen_cell_microcode
9498    && (!avoiding_indexed_address_p (SImode)
9499        || !gpc_reg_operand (operands[2], SImode))"
9500   "@
9501    lhaux %3,%0,%2
9502    lhau %3,%2(%0)"
9503   [(set_attr "type" "load")
9504    (set_attr "sign_extend" "yes")
9505    (set_attr "update" "yes")
9506    (set_attr "indexed" "yes,no")])
9508 (define_insn "*movhi_update4"
9509   [(set (mem:HI (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:HI 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   "@
9518    sthux %3,%0,%2
9519    sthu %3,%2(%0)"
9520   [(set_attr "type" "store")
9521    (set_attr "update" "yes")
9522    (set_attr "indexed" "yes,no")])
9524 (define_insn "*movqi_update1"
9525   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9526         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9527                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9528    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9529         (plus:SI (match_dup 1) (match_dup 2)))]
9530   "TARGET_UPDATE
9531    && (!avoiding_indexed_address_p (SImode)
9532        || !gpc_reg_operand (operands[2], SImode))"
9533   "@
9534    lbzux %3,%0,%2
9535    lbzu %3,%2(%0)"
9536   [(set_attr "type" "load")
9537    (set_attr "update" "yes")
9538    (set_attr "indexed" "yes,no")])
9540 (define_insn "*movqi_update2"
9541   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9542         (zero_extend:SI
9543          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9544                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9545    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9546         (plus:SI (match_dup 1) (match_dup 2)))]
9547   "TARGET_UPDATE
9548    && (!avoiding_indexed_address_p (SImode)
9549        || !gpc_reg_operand (operands[2], SImode))"
9550   "@
9551    lbzux %3,%0,%2
9552    lbzu %3,%2(%0)"
9553   [(set_attr "type" "load")
9554    (set_attr "update" "yes")
9555    (set_attr "indexed" "yes,no")])
9557 (define_insn "*movqi_update3"
9558   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9559                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9560         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9561    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9562         (plus:SI (match_dup 1) (match_dup 2)))]
9563   "TARGET_UPDATE
9564    && (!avoiding_indexed_address_p (SImode)
9565        || !gpc_reg_operand (operands[2], SImode))"
9566   "@
9567    stbux %3,%0,%2
9568    stbu %3,%2(%0)"
9569   [(set_attr "type" "store")
9570    (set_attr "update" "yes")
9571    (set_attr "indexed" "yes,no")])
9573 (define_insn "*movsf_update1"
9574   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9575         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9576                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9577    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9578         (plus:SI (match_dup 1) (match_dup 2)))]
9579   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9580    && (!avoiding_indexed_address_p (SImode)
9581        || !gpc_reg_operand (operands[2], SImode))"
9582   "@
9583    lfsux %3,%0,%2
9584    lfsu %3,%2(%0)"
9585   [(set_attr "type" "fpload")
9586    (set_attr "update" "yes")
9587    (set_attr "indexed" "yes,no")])
9589 (define_insn "*movsf_update2"
9590   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9591                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9592         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9593    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9594         (plus:SI (match_dup 1) (match_dup 2)))]
9595   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9596    && (!avoiding_indexed_address_p (SImode)
9597        || !gpc_reg_operand (operands[2], SImode))"
9598   "@
9599    stfsux %3,%0,%2
9600    stfsu %3,%2(%0)"
9601   [(set_attr "type" "fpstore")
9602    (set_attr "update" "yes")
9603    (set_attr "indexed" "yes,no")])
9605 (define_insn "*movsf_update3"
9606   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9607         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9608                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9609    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9610         (plus:SI (match_dup 1) (match_dup 2)))]
9611   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9612    && (!avoiding_indexed_address_p (SImode)
9613        || !gpc_reg_operand (operands[2], SImode))"
9614   "@
9615    lwzux %3,%0,%2
9616    lwzu %3,%2(%0)"
9617   [(set_attr "type" "load")
9618    (set_attr "update" "yes")
9619    (set_attr "indexed" "yes,no")])
9621 (define_insn "*movsf_update4"
9622   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9623                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9624         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9625    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9626         (plus:SI (match_dup 1) (match_dup 2)))]
9627   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9628    && (!avoiding_indexed_address_p (SImode)
9629        || !gpc_reg_operand (operands[2], SImode))"
9630   "@
9631    stwux %3,%0,%2
9632    stwu %3,%2(%0)"
9633   [(set_attr "type" "store")
9634    (set_attr "update" "yes")
9635    (set_attr "indexed" "yes,no")])
9637 (define_insn "*movdf_update1"
9638   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9639         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9640                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9641    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9642         (plus:SI (match_dup 1) (match_dup 2)))]
9643   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9644    && (!avoiding_indexed_address_p (SImode)
9645        || !gpc_reg_operand (operands[2], SImode))"
9646   "@
9647    lfdux %3,%0,%2
9648    lfdu %3,%2(%0)"
9649   [(set_attr "type" "fpload")
9650    (set_attr "update" "yes")
9651    (set_attr "indexed" "yes,no")
9652    (set_attr "size" "64")])
9654 (define_insn "*movdf_update2"
9655   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9656                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9657         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9658    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9659         (plus:SI (match_dup 1) (match_dup 2)))]
9660   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9661    && (!avoiding_indexed_address_p (SImode)
9662        || !gpc_reg_operand (operands[2], SImode))"
9663   "@
9664    stfdux %3,%0,%2
9665    stfdu %3,%2(%0)"
9666   [(set_attr "type" "fpstore")
9667    (set_attr "update" "yes")
9668    (set_attr "indexed" "yes,no")])
9671 ;; After inserting conditional returns we can sometimes have
9672 ;; unnecessary register moves.  Unfortunately we cannot have a
9673 ;; modeless peephole here, because some single SImode sets have early
9674 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9675 ;; sequences, using get_attr_length here will smash the operands
9676 ;; array.  Neither is there an early_cobbler_p predicate.
9677 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9678 ;; Also this optimization interferes with scalars going into
9679 ;; altivec registers (the code does reloading through the FPRs).
9680 (define_peephole2
9681   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9682         (match_operand:DF 1 "any_operand" ""))
9683    (set (match_operand:DF 2 "gpc_reg_operand" "")
9684         (match_dup 0))]
9685   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9686    && !TARGET_UPPER_REGS_DF
9687    && peep2_reg_dead_p (2, operands[0])"
9688   [(set (match_dup 2) (match_dup 1))])
9690 (define_peephole2
9691   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9692         (match_operand:SF 1 "any_operand" ""))
9693    (set (match_operand:SF 2 "gpc_reg_operand" "")
9694         (match_dup 0))]
9695   "!TARGET_UPPER_REGS_SF
9696    && peep2_reg_dead_p (2, operands[0])"
9697   [(set (match_dup 2) (match_dup 1))])
9700 ;; TLS support.
9702 ;; Mode attributes for different ABIs.
9703 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9704 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9705 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9706 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9708 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9709   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9710         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9711               (match_operand 4 "" "g")))
9712    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9713                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9714                    UNSPEC_TLSGD)
9715    (clobber (reg:SI LR_REGNO))]
9716   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9718   if (TARGET_CMODEL != CMODEL_SMALL)
9719     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9720            "bl %z3\;nop";
9721   else
9722     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9724   "&& TARGET_TLS_MARKERS"
9725   [(set (match_dup 0)
9726         (unspec:TLSmode [(match_dup 1)
9727                          (match_dup 2)]
9728                         UNSPEC_TLSGD))
9729    (parallel [(set (match_dup 0)
9730                    (call (mem:TLSmode (match_dup 3))
9731                          (match_dup 4)))
9732               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9733               (clobber (reg:SI LR_REGNO))])]
9734   ""
9735   [(set_attr "type" "two")
9736    (set (attr "length")
9737      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9738                    (const_int 16)
9739                    (const_int 12)))])
9741 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9742   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9743         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9744               (match_operand 4 "" "g")))
9745    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9746                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9747                    UNSPEC_TLSGD)
9748    (clobber (reg:SI LR_REGNO))]
9749   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9751   if (flag_pic)
9752     {
9753       if (TARGET_SECURE_PLT && flag_pic == 2)
9754         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9755       else
9756         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9757     }
9758   else
9759     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9761   "&& TARGET_TLS_MARKERS"
9762   [(set (match_dup 0)
9763         (unspec:TLSmode [(match_dup 1)
9764                          (match_dup 2)]
9765                         UNSPEC_TLSGD))
9766    (parallel [(set (match_dup 0)
9767                    (call (mem:TLSmode (match_dup 3))
9768                          (match_dup 4)))
9769               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9770               (clobber (reg:SI LR_REGNO))])]
9771   ""
9772   [(set_attr "type" "two")
9773    (set_attr "length" "8")])
9775 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9776   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9777         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9778                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9779                         UNSPEC_TLSGD))]
9780   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9781   "addi %0,%1,%2@got@tlsgd"
9782   "&& TARGET_CMODEL != CMODEL_SMALL"
9783   [(set (match_dup 3)
9784         (high:TLSmode
9785             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9786    (set (match_dup 0)
9787         (lo_sum:TLSmode (match_dup 3)
9788             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9789   "
9791   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9793   [(set (attr "length")
9794      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9795                    (const_int 8)
9796                    (const_int 4)))])
9798 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9799   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9800      (high:TLSmode
9801        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9802                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9803                        UNSPEC_TLSGD)))]
9804   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9805   "addis %0,%1,%2@got@tlsgd@ha"
9806   [(set_attr "length" "4")])
9808 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9809   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9810      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9811        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9812                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9813                        UNSPEC_TLSGD)))]
9814   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9815   "addi %0,%1,%2@got@tlsgd@l"
9816   [(set_attr "length" "4")])
9818 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9819   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9820         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9821               (match_operand 2 "" "g")))
9822    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9823                    UNSPEC_TLSGD)
9824    (clobber (reg:SI LR_REGNO))]
9825   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9826    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9827   "bl %z1(%3@tlsgd)\;nop"
9828   [(set_attr "type" "branch")
9829    (set_attr "length" "8")])
9831 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9832   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9833         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9834               (match_operand 2 "" "g")))
9835    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9836                    UNSPEC_TLSGD)
9837    (clobber (reg:SI LR_REGNO))]
9838   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9840   if (flag_pic)
9841     {
9842       if (TARGET_SECURE_PLT && flag_pic == 2)
9843         return "bl %z1+32768(%3@tlsgd)@plt";
9844       return "bl %z1(%3@tlsgd)@plt";
9845     }
9846   return "bl %z1(%3@tlsgd)";
9848   [(set_attr "type" "branch")
9849    (set_attr "length" "4")])
9851 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9852   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9853         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9854               (match_operand 3 "" "g")))
9855    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9856                    UNSPEC_TLSLD)
9857    (clobber (reg:SI LR_REGNO))]
9858   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9860   if (TARGET_CMODEL != CMODEL_SMALL)
9861     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9862            "bl %z2\;nop";
9863   else
9864     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9866   "&& TARGET_TLS_MARKERS"
9867   [(set (match_dup 0)
9868         (unspec:TLSmode [(match_dup 1)]
9869                         UNSPEC_TLSLD))
9870    (parallel [(set (match_dup 0)
9871                    (call (mem:TLSmode (match_dup 2))
9872                          (match_dup 3)))
9873               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9874               (clobber (reg:SI LR_REGNO))])]
9875   ""
9876   [(set_attr "type" "two")
9877    (set (attr "length")
9878      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9879                    (const_int 16)
9880                    (const_int 12)))])
9882 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9883   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9884         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9885               (match_operand 3 "" "g")))
9886    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9887                    UNSPEC_TLSLD)
9888    (clobber (reg:SI LR_REGNO))]
9889   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9891   if (flag_pic)
9892     {
9893       if (TARGET_SECURE_PLT && flag_pic == 2)
9894         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9895       else
9896         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9897     }
9898   else
9899     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9901   "&& TARGET_TLS_MARKERS"
9902   [(set (match_dup 0)
9903         (unspec:TLSmode [(match_dup 1)]
9904                         UNSPEC_TLSLD))
9905    (parallel [(set (match_dup 0)
9906                    (call (mem:TLSmode (match_dup 2))
9907                          (match_dup 3)))
9908               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9909               (clobber (reg:SI LR_REGNO))])]
9910   ""
9911   [(set_attr "length" "8")])
9913 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9914   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9915         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9916                         UNSPEC_TLSLD))]
9917   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9918   "addi %0,%1,%&@got@tlsld"
9919   "&& TARGET_CMODEL != CMODEL_SMALL"
9920   [(set (match_dup 2)
9921         (high:TLSmode
9922             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9923    (set (match_dup 0)
9924         (lo_sum:TLSmode (match_dup 2)
9925             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9926   "
9928   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9930   [(set (attr "length")
9931      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9932                    (const_int 8)
9933                    (const_int 4)))])
9935 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9936   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9937      (high:TLSmode
9938        (unspec:TLSmode [(const_int 0)
9939                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9940                        UNSPEC_TLSLD)))]
9941   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9942   "addis %0,%1,%&@got@tlsld@ha"
9943   [(set_attr "length" "4")])
9945 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9946   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9947      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9948        (unspec:TLSmode [(const_int 0)
9949                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9950                        UNSPEC_TLSLD)))]
9951   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9952   "addi %0,%1,%&@got@tlsld@l"
9953   [(set_attr "length" "4")])
9955 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9956   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9957         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9958               (match_operand 2 "" "g")))
9959    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9960    (clobber (reg:SI LR_REGNO))]
9961   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9962    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9963   "bl %z1(%&@tlsld)\;nop"
9964   [(set_attr "type" "branch")
9965    (set_attr "length" "8")])
9967 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9968   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9969         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9970               (match_operand 2 "" "g")))
9971    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9972    (clobber (reg:SI LR_REGNO))]
9973   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9975   if (flag_pic)
9976     {
9977       if (TARGET_SECURE_PLT && flag_pic == 2)
9978         return "bl %z1+32768(%&@tlsld)@plt";
9979       return "bl %z1(%&@tlsld)@plt";
9980     }
9981   return "bl %z1(%&@tlsld)";
9983   [(set_attr "type" "branch")
9984    (set_attr "length" "4")])
9986 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9987   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9988         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9989                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9990                         UNSPEC_TLSDTPREL))]
9991   "HAVE_AS_TLS"
9992   "addi %0,%1,%2@dtprel")
9994 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9995   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9996         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9997                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9998                         UNSPEC_TLSDTPRELHA))]
9999   "HAVE_AS_TLS"
10000   "addis %0,%1,%2@dtprel@ha")
10002 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10003   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10004         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10005                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10006                         UNSPEC_TLSDTPRELLO))]
10007   "HAVE_AS_TLS"
10008   "addi %0,%1,%2@dtprel@l")
10010 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10011   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10012         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10013                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10014                         UNSPEC_TLSGOTDTPREL))]
10015   "HAVE_AS_TLS"
10016   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10017   "&& TARGET_CMODEL != CMODEL_SMALL"
10018   [(set (match_dup 3)
10019         (high:TLSmode
10020             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10021    (set (match_dup 0)
10022         (lo_sum:TLSmode (match_dup 3)
10023             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10024   "
10026   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10028   [(set (attr "length")
10029      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10030                    (const_int 8)
10031                    (const_int 4)))])
10033 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10034   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10035      (high:TLSmode
10036        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10037                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10038                        UNSPEC_TLSGOTDTPREL)))]
10039   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10040   "addis %0,%1,%2@got@dtprel@ha"
10041   [(set_attr "length" "4")])
10043 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10044   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10045      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10046          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10047                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10048                          UNSPEC_TLSGOTDTPREL)))]
10049   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10050   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10051   [(set_attr "length" "4")])
10053 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10054   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10055         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10056                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10057                         UNSPEC_TLSTPREL))]
10058   "HAVE_AS_TLS"
10059   "addi %0,%1,%2@tprel")
10061 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10062   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10063         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10064                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10065                         UNSPEC_TLSTPRELHA))]
10066   "HAVE_AS_TLS"
10067   "addis %0,%1,%2@tprel@ha")
10069 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10070   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10071         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10072                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10073                         UNSPEC_TLSTPRELLO))]
10074   "HAVE_AS_TLS"
10075   "addi %0,%1,%2@tprel@l")
10077 ;; "b" output constraint here and on tls_tls input to support linker tls
10078 ;; optimization.  The linker may edit the instructions emitted by a
10079 ;; tls_got_tprel/tls_tls pair to addis,addi.
10080 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10081   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10082         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10083                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10084                         UNSPEC_TLSGOTTPREL))]
10085   "HAVE_AS_TLS"
10086   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10087   "&& TARGET_CMODEL != CMODEL_SMALL"
10088   [(set (match_dup 3)
10089         (high:TLSmode
10090             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10091    (set (match_dup 0)
10092         (lo_sum:TLSmode (match_dup 3)
10093             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10094   "
10096   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10098   [(set (attr "length")
10099      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10100                    (const_int 8)
10101                    (const_int 4)))])
10103 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10104   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10105      (high:TLSmode
10106        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10107                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10108                        UNSPEC_TLSGOTTPREL)))]
10109   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10110   "addis %0,%1,%2@got@tprel@ha"
10111   [(set_attr "length" "4")])
10113 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10114   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10115      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10116          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10117                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10118                          UNSPEC_TLSGOTTPREL)))]
10119   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10120   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10121   [(set_attr "length" "4")])
10123 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10124   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10125         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10126                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10127                         UNSPEC_TLSTLS))]
10128   "TARGET_ELF && HAVE_AS_TLS"
10129   "add %0,%1,%2@tls")
10131 (define_expand "tls_get_tpointer"
10132   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10133         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10134   "TARGET_XCOFF && HAVE_AS_TLS"
10135   "
10137   emit_insn (gen_tls_get_tpointer_internal ());
10138   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10139   DONE;
10142 (define_insn "tls_get_tpointer_internal"
10143   [(set (reg:SI 3)
10144         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10145    (clobber (reg:SI LR_REGNO))]
10146   "TARGET_XCOFF && HAVE_AS_TLS"
10147   "bla __get_tpointer")
10149 (define_expand "tls_get_addr<mode>"
10150   [(set (match_operand:P 0 "gpc_reg_operand" "")
10151         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10152                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10153   "TARGET_XCOFF && HAVE_AS_TLS"
10154   "
10156   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10157   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10158   emit_insn (gen_tls_get_addr_internal<mode> ());
10159   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10160   DONE;
10163 (define_insn "tls_get_addr_internal<mode>"
10164   [(set (reg:P 3)
10165         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10166    (clobber (reg:P 0))
10167    (clobber (reg:P 4))
10168    (clobber (reg:P 5))
10169    (clobber (reg:P 11))
10170    (clobber (reg:CC CR0_REGNO))
10171    (clobber (reg:P LR_REGNO))]
10172   "TARGET_XCOFF && HAVE_AS_TLS"
10173   "bla __tls_get_addr")
10175 ;; Next come insns related to the calling sequence.
10177 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10178 ;; We move the back-chain and decrement the stack pointer.
10180 (define_expand "allocate_stack"
10181   [(set (match_operand 0 "gpc_reg_operand" "")
10182         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10183    (set (reg 1)
10184         (minus (reg 1) (match_dup 1)))]
10185   ""
10186   "
10187 { rtx chain = gen_reg_rtx (Pmode);
10188   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10189   rtx neg_op0;
10190   rtx insn, par, set, mem;
10192   emit_move_insn (chain, stack_bot);
10194   /* Check stack bounds if necessary.  */
10195   if (crtl->limit_stack)
10196     {
10197       rtx available;
10198       available = expand_binop (Pmode, sub_optab,
10199                                 stack_pointer_rtx, stack_limit_rtx,
10200                                 NULL_RTX, 1, OPTAB_WIDEN);
10201       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10202     }
10204   if (GET_CODE (operands[1]) != CONST_INT
10205       || INTVAL (operands[1]) < -32767
10206       || INTVAL (operands[1]) > 32768)
10207     {
10208       neg_op0 = gen_reg_rtx (Pmode);
10209       if (TARGET_32BIT)
10210         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10211       else
10212         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10213     }
10214   else
10215     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10217   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10218                                        : gen_movdi_di_update_stack))
10219                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10220                          chain));
10221   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10222      it now and set the alias set/attributes. The above gen_*_update
10223      calls will generate a PARALLEL with the MEM set being the first
10224      operation. */
10225   par = PATTERN (insn);
10226   gcc_assert (GET_CODE (par) == PARALLEL);
10227   set = XVECEXP (par, 0, 0);
10228   gcc_assert (GET_CODE (set) == SET);
10229   mem = SET_DEST (set);
10230   gcc_assert (MEM_P (mem));
10231   MEM_NOTRAP_P (mem) = 1;
10232   set_mem_alias_set (mem, get_frame_alias_set ());
10234   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10235   DONE;
10238 ;; These patterns say how to save and restore the stack pointer.  We need not
10239 ;; save the stack pointer at function level since we are careful to
10240 ;; preserve the backchain.  At block level, we have to restore the backchain
10241 ;; when we restore the stack pointer.
10243 ;; For nonlocal gotos, we must save both the stack pointer and its
10244 ;; backchain and restore both.  Note that in the nonlocal case, the
10245 ;; save area is a memory location.
10247 (define_expand "save_stack_function"
10248   [(match_operand 0 "any_operand" "")
10249    (match_operand 1 "any_operand" "")]
10250   ""
10251   "DONE;")
10253 (define_expand "restore_stack_function"
10254   [(match_operand 0 "any_operand" "")
10255    (match_operand 1 "any_operand" "")]
10256   ""
10257   "DONE;")
10259 ;; Adjust stack pointer (op0) to a new value (op1).
10260 ;; First copy old stack backchain to new location, and ensure that the
10261 ;; scheduler won't reorder the sp assignment before the backchain write.
10262 (define_expand "restore_stack_block"
10263   [(set (match_dup 2) (match_dup 3))
10264    (set (match_dup 4) (match_dup 2))
10265    (match_dup 5)
10266    (set (match_operand 0 "register_operand" "")
10267         (match_operand 1 "register_operand" ""))]
10268   ""
10269   "
10271   rtvec p;
10273   operands[1] = force_reg (Pmode, operands[1]);
10274   operands[2] = gen_reg_rtx (Pmode);
10275   operands[3] = gen_frame_mem (Pmode, operands[0]);
10276   operands[4] = gen_frame_mem (Pmode, operands[1]);
10277   p = rtvec_alloc (1);
10278   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10279                                   const0_rtx);
10280   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10283 (define_expand "save_stack_nonlocal"
10284   [(set (match_dup 3) (match_dup 4))
10285    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10286    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10287   ""
10288   "
10290   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10292   /* Copy the backchain to the first word, sp to the second.  */
10293   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10294   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10295   operands[3] = gen_reg_rtx (Pmode);
10296   operands[4] = gen_frame_mem (Pmode, operands[1]);
10299 (define_expand "restore_stack_nonlocal"
10300   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10301    (set (match_dup 3) (match_dup 4))
10302    (set (match_dup 5) (match_dup 2))
10303    (match_dup 6)
10304    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10305   ""
10306   "
10308   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10309   rtvec p;
10311   /* Restore the backchain from the first word, sp from the second.  */
10312   operands[2] = gen_reg_rtx (Pmode);
10313   operands[3] = gen_reg_rtx (Pmode);
10314   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10315   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10316   operands[5] = gen_frame_mem (Pmode, operands[3]);
10317   p = rtvec_alloc (1);
10318   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10319                                   const0_rtx);
10320   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10323 ;; TOC register handling.
10325 ;; Code to initialize the TOC register...
10327 (define_insn "load_toc_aix_si"
10328   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10329                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10330               (use (reg:SI 2))])]
10331   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10332   "*
10334   char buf[30];
10335   extern int need_toc_init;
10336   need_toc_init = 1;
10337   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10338   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10339   operands[2] = gen_rtx_REG (Pmode, 2);
10340   return \"lwz %0,%1(%2)\";
10342   [(set_attr "type" "load")
10343    (set_attr "update" "no")
10344    (set_attr "indexed" "no")])
10346 (define_insn "load_toc_aix_di"
10347   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10348                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10349               (use (reg:DI 2))])]
10350   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10351   "*
10353   char buf[30];
10354   extern int need_toc_init;
10355   need_toc_init = 1;
10356   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10357                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10358   if (TARGET_ELF)
10359     strcat (buf, \"@toc\");
10360   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10361   operands[2] = gen_rtx_REG (Pmode, 2);
10362   return \"ld %0,%1(%2)\";
10364   [(set_attr "type" "load")
10365    (set_attr "update" "no")
10366    (set_attr "indexed" "no")])
10368 (define_insn "load_toc_v4_pic_si"
10369   [(set (reg:SI LR_REGNO)
10370         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10371   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10372   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10373   [(set_attr "type" "branch")
10374    (set_attr "length" "4")])
10376 (define_expand "load_toc_v4_PIC_1"
10377   [(parallel [(set (reg:SI LR_REGNO)
10378                    (match_operand:SI 0 "immediate_operand" "s"))
10379               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10380   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10381    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10382   "")
10384 (define_insn "load_toc_v4_PIC_1_normal"
10385   [(set (reg:SI LR_REGNO)
10386         (match_operand:SI 0 "immediate_operand" "s"))
10387    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10388   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10389    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10390   "bcl 20,31,%0\\n%0:"
10391   [(set_attr "type" "branch")
10392    (set_attr "length" "4")
10393    (set_attr "cannot_copy" "yes")])
10395 (define_insn "load_toc_v4_PIC_1_476"
10396   [(set (reg:SI LR_REGNO)
10397         (match_operand:SI 0 "immediate_operand" "s"))
10398    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10399   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10400    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10401   "*
10403   char name[32];
10404   static char templ[32];
10406   get_ppc476_thunk_name (name);
10407   sprintf (templ, \"bl %s\\n%%0:\", name);
10408   return templ;
10410   [(set_attr "type" "branch")
10411    (set_attr "length" "4")
10412    (set_attr "cannot_copy" "yes")])
10414 (define_expand "load_toc_v4_PIC_1b"
10415   [(parallel [(set (reg:SI LR_REGNO)
10416                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10417                                (label_ref (match_operand 1 "" ""))]
10418                            UNSPEC_TOCPTR))
10419               (match_dup 1)])]
10420   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10421   "")
10423 (define_insn "load_toc_v4_PIC_1b_normal"
10424   [(set (reg:SI LR_REGNO)
10425         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10426                     (label_ref (match_operand 1 "" ""))]
10427                 UNSPEC_TOCPTR))
10428    (match_dup 1)]
10429   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10430   "bcl 20,31,$+8\;.long %0-$"
10431   [(set_attr "type" "branch")
10432    (set_attr "length" "8")])
10434 (define_insn "load_toc_v4_PIC_1b_476"
10435   [(set (reg:SI LR_REGNO)
10436         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10437                     (label_ref (match_operand 1 "" ""))]
10438                 UNSPEC_TOCPTR))
10439    (match_dup 1)]
10440   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10441   "*
10443   char name[32];
10444   static char templ[32];
10446   get_ppc476_thunk_name (name);
10447   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10448   return templ;
10450   [(set_attr "type" "branch")
10451    (set_attr "length" "16")])
10453 (define_insn "load_toc_v4_PIC_2"
10454   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10455         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10456                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10457                              (match_operand:SI 3 "immediate_operand" "s")))))]
10458   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10459   "lwz %0,%2-%3(%1)"
10460   [(set_attr "type" "load")])
10462 (define_insn "load_toc_v4_PIC_3b"
10463   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10464         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10465                  (high:SI
10466                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10467                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10468   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10469   "addis %0,%1,%2-%3@ha")
10471 (define_insn "load_toc_v4_PIC_3c"
10472   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10473         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10474                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10475                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10476   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10477   "addi %0,%1,%2-%3@l")
10479 ;; If the TOC is shared over a translation unit, as happens with all
10480 ;; the kinds of PIC that we support, we need to restore the TOC
10481 ;; pointer only when jumping over units of translation.
10482 ;; On Darwin, we need to reload the picbase.
10484 (define_expand "builtin_setjmp_receiver"
10485   [(use (label_ref (match_operand 0 "" "")))]
10486   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10487    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10488    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10489   "
10491 #if TARGET_MACHO
10492   if (DEFAULT_ABI == ABI_DARWIN)
10493     {
10494       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10495       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10496       rtx tmplabrtx;
10497       char tmplab[20];
10499       crtl->uses_pic_offset_table = 1;
10500       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10501                                   CODE_LABEL_NUMBER (operands[0]));
10502       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10504       emit_insn (gen_load_macho_picbase (tmplabrtx));
10505       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10506       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10507     }
10508   else
10509 #endif
10510     rs6000_emit_load_toc_table (FALSE);
10511   DONE;
10514 ;; Largetoc support
10515 (define_insn "*largetoc_high"
10516   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10517         (high:DI
10518           (unspec [(match_operand:DI 1 "" "")
10519                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10520                   UNSPEC_TOCREL)))]
10521    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10522    "addis %0,%2,%1@toc@ha")
10524 (define_insn "*largetoc_high_aix<mode>"
10525   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10526         (high:P
10527           (unspec [(match_operand:P 1 "" "")
10528                    (match_operand:P 2 "gpc_reg_operand" "b")]
10529                   UNSPEC_TOCREL)))]
10530    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10531    "addis %0,%1@u(%2)")
10533 (define_insn "*largetoc_high_plus"
10534   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10535         (high:DI
10536           (plus:DI
10537             (unspec [(match_operand:DI 1 "" "")
10538                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10539                     UNSPEC_TOCREL)
10540             (match_operand:DI 3 "add_cint_operand" "n"))))]
10541    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10542    "addis %0,%2,%1+%3@toc@ha")
10544 (define_insn "*largetoc_high_plus_aix<mode>"
10545   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10546         (high:P
10547           (plus:P
10548             (unspec [(match_operand:P 1 "" "")
10549                      (match_operand:P 2 "gpc_reg_operand" "b")]
10550                     UNSPEC_TOCREL)
10551             (match_operand:P 3 "add_cint_operand" "n"))))]
10552    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10553    "addis %0,%1+%3@u(%2)")
10555 (define_insn "*largetoc_low"
10556   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10557         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10558                    (match_operand:DI 2 "" "")))]
10559    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10560    "addi %0,%1,%2@l")
10562 (define_insn "*largetoc_low_aix<mode>"
10563   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10564         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10565                    (match_operand:P 2 "" "")))]
10566    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10567    "la %0,%2@l(%1)")
10569 (define_insn_and_split "*tocref<mode>"
10570   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10571         (match_operand:P 1 "small_toc_ref" "R"))]
10572    "TARGET_TOC"
10573    "la %0,%a1"
10574    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10575   [(set (match_dup 0) (high:P (match_dup 1)))
10576    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10578 ;; Elf specific ways of loading addresses for non-PIC code.
10579 ;; The output of this could be r0, but we make a very strong
10580 ;; preference for a base register because it will usually
10581 ;; be needed there.
10582 (define_insn "elf_high"
10583   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10584         (high:SI (match_operand 1 "" "")))]
10585   "TARGET_ELF && ! TARGET_64BIT"
10586   "lis %0,%1@ha")
10588 (define_insn "elf_low"
10589   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10590         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10591                    (match_operand 2 "" "")))]
10592    "TARGET_ELF && ! TARGET_64BIT"
10593    "la %0,%2@l(%1)")
10595 ;; Call and call_value insns
10596 (define_expand "call"
10597   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10598                     (match_operand 1 "" ""))
10599               (use (match_operand 2 "" ""))
10600               (clobber (reg:SI LR_REGNO))])]
10601   ""
10602   "
10604 #if TARGET_MACHO
10605   if (MACHOPIC_INDIRECT)
10606     operands[0] = machopic_indirect_call_target (operands[0]);
10607 #endif
10609   gcc_assert (GET_CODE (operands[0]) == MEM);
10610   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10612   operands[0] = XEXP (operands[0], 0);
10614   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10615     {
10616       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10617       DONE;
10618     }
10620   if (GET_CODE (operands[0]) != SYMBOL_REF
10621       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10622     {
10623       if (INTVAL (operands[2]) & CALL_LONG)
10624         operands[0] = rs6000_longcall_ref (operands[0]);
10626       switch (DEFAULT_ABI)
10627         {
10628         case ABI_V4:
10629         case ABI_DARWIN:
10630           operands[0] = force_reg (Pmode, operands[0]);
10631           break;
10633         default:
10634           gcc_unreachable ();
10635         }
10636     }
10639 (define_expand "call_value"
10640   [(parallel [(set (match_operand 0 "" "")
10641                    (call (mem:SI (match_operand 1 "address_operand" ""))
10642                          (match_operand 2 "" "")))
10643               (use (match_operand 3 "" ""))
10644               (clobber (reg:SI LR_REGNO))])]
10645   ""
10646   "
10648 #if TARGET_MACHO
10649   if (MACHOPIC_INDIRECT)
10650     operands[1] = machopic_indirect_call_target (operands[1]);
10651 #endif
10653   gcc_assert (GET_CODE (operands[1]) == MEM);
10654   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10656   operands[1] = XEXP (operands[1], 0);
10658   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10659     {
10660       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10661       DONE;
10662     }
10664   if (GET_CODE (operands[1]) != SYMBOL_REF
10665       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10666     {
10667       if (INTVAL (operands[3]) & CALL_LONG)
10668         operands[1] = rs6000_longcall_ref (operands[1]);
10670       switch (DEFAULT_ABI)
10671         {
10672         case ABI_V4:
10673         case ABI_DARWIN:
10674           operands[1] = force_reg (Pmode, operands[1]);
10675           break;
10677         default:
10678           gcc_unreachable ();
10679         }
10680     }
10683 ;; Call to function in current module.  No TOC pointer reload needed.
10684 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10685 ;; either the function was not prototyped, or it was prototyped as a
10686 ;; variable argument function.  It is > 0 if FP registers were passed
10687 ;; and < 0 if they were not.
10689 (define_insn "*call_local32"
10690   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10691          (match_operand 1 "" "g,g"))
10692    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10693    (clobber (reg:SI LR_REGNO))]
10694   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10695   "*
10697   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10698     output_asm_insn (\"crxor 6,6,6\", operands);
10700   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10701     output_asm_insn (\"creqv 6,6,6\", operands);
10703   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10705   [(set_attr "type" "branch")
10706    (set_attr "length" "4,8")])
10708 (define_insn "*call_local64"
10709   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10710          (match_operand 1 "" "g,g"))
10711    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10712    (clobber (reg:SI LR_REGNO))]
10713   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10714   "*
10716   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10717     output_asm_insn (\"crxor 6,6,6\", operands);
10719   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10720     output_asm_insn (\"creqv 6,6,6\", operands);
10722   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10724   [(set_attr "type" "branch")
10725    (set_attr "length" "4,8")])
10727 (define_insn "*call_value_local32"
10728   [(set (match_operand 0 "" "")
10729         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10730               (match_operand 2 "" "g,g")))
10731    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10732    (clobber (reg:SI LR_REGNO))]
10733   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10734   "*
10736   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10737     output_asm_insn (\"crxor 6,6,6\", operands);
10739   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10740     output_asm_insn (\"creqv 6,6,6\", operands);
10742   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10744   [(set_attr "type" "branch")
10745    (set_attr "length" "4,8")])
10748 (define_insn "*call_value_local64"
10749   [(set (match_operand 0 "" "")
10750         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10751               (match_operand 2 "" "g,g")))
10752    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10753    (clobber (reg:SI LR_REGNO))]
10754   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10755   "*
10757   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10758     output_asm_insn (\"crxor 6,6,6\", operands);
10760   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10761     output_asm_insn (\"creqv 6,6,6\", operands);
10763   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10765   [(set_attr "type" "branch")
10766    (set_attr "length" "4,8")])
10769 ;; A function pointer under System V is just a normal pointer
10770 ;; operands[0] is the function pointer
10771 ;; operands[1] is the stack size to clean up
10772 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10773 ;; which indicates how to set cr1
10775 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10776   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10777          (match_operand 1 "" "g,g,g,g"))
10778    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10779    (clobber (reg:SI LR_REGNO))]
10780   "DEFAULT_ABI == ABI_V4
10781    || DEFAULT_ABI == ABI_DARWIN"
10783   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10784     output_asm_insn ("crxor 6,6,6", operands);
10786   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10787     output_asm_insn ("creqv 6,6,6", operands);
10789   return "b%T0l";
10791   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10792    (set_attr "length" "4,4,8,8")])
10794 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10795   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10796          (match_operand 1 "" "g,g"))
10797    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10798    (clobber (reg:SI LR_REGNO))]
10799   "(DEFAULT_ABI == ABI_DARWIN
10800    || (DEFAULT_ABI == ABI_V4
10801        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10803   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10804     output_asm_insn ("crxor 6,6,6", operands);
10806   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10807     output_asm_insn ("creqv 6,6,6", operands);
10809 #if TARGET_MACHO
10810   return output_call(insn, operands, 0, 2);
10811 #else
10812   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10813     {
10814       gcc_assert (!TARGET_SECURE_PLT);
10815       return "bl %z0@plt";
10816     }
10817   else
10818     return "bl %z0";
10819 #endif
10821   "DEFAULT_ABI == ABI_V4
10822    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10823    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10824   [(parallel [(call (mem:SI (match_dup 0))
10825                     (match_dup 1))
10826               (use (match_dup 2))
10827               (use (match_dup 3))
10828               (clobber (reg:SI LR_REGNO))])]
10830   operands[3] = pic_offset_table_rtx;
10832   [(set_attr "type" "branch,branch")
10833    (set_attr "length" "4,8")])
10835 (define_insn "*call_nonlocal_sysv_secure<mode>"
10836   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10837          (match_operand 1 "" "g,g"))
10838    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10839    (use (match_operand:SI 3 "register_operand" "r,r"))
10840    (clobber (reg:SI LR_REGNO))]
10841   "(DEFAULT_ABI == ABI_V4
10842     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10843     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10845   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10846     output_asm_insn ("crxor 6,6,6", operands);
10848   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10849     output_asm_insn ("creqv 6,6,6", operands);
10851   if (flag_pic == 2)
10852     /* The magic 32768 offset here and in the other sysv call insns
10853        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10854        See sysv4.h:toc_section.  */
10855     return "bl %z0+32768@plt";
10856   else
10857     return "bl %z0@plt";
10859   [(set_attr "type" "branch,branch")
10860    (set_attr "length" "4,8")])
10862 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10863   [(set (match_operand 0 "" "")
10864         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10865               (match_operand 2 "" "g,g,g,g")))
10866    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10867    (clobber (reg:SI LR_REGNO))]
10868   "DEFAULT_ABI == ABI_V4
10869    || DEFAULT_ABI == ABI_DARWIN"
10871   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10872     output_asm_insn ("crxor 6,6,6", operands);
10874   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10875     output_asm_insn ("creqv 6,6,6", operands);
10877   return "b%T1l";
10879   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10880    (set_attr "length" "4,4,8,8")])
10882 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10883   [(set (match_operand 0 "" "")
10884         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10885               (match_operand 2 "" "g,g")))
10886    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10887    (clobber (reg:SI LR_REGNO))]
10888   "(DEFAULT_ABI == ABI_DARWIN
10889    || (DEFAULT_ABI == ABI_V4
10890        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10892   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10893     output_asm_insn ("crxor 6,6,6", operands);
10895   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10896     output_asm_insn ("creqv 6,6,6", operands);
10898 #if TARGET_MACHO
10899   return output_call(insn, operands, 1, 3);
10900 #else
10901   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10902     {
10903       gcc_assert (!TARGET_SECURE_PLT);
10904       return "bl %z1@plt";
10905     }
10906   else
10907     return "bl %z1";
10908 #endif
10910   "DEFAULT_ABI == ABI_V4
10911    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10912    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10913   [(parallel [(set (match_dup 0)
10914                    (call (mem:SI (match_dup 1))
10915                          (match_dup 2)))
10916               (use (match_dup 3))
10917               (use (match_dup 4))
10918               (clobber (reg:SI LR_REGNO))])]
10920   operands[4] = pic_offset_table_rtx;
10922   [(set_attr "type" "branch,branch")
10923    (set_attr "length" "4,8")])
10925 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10926   [(set (match_operand 0 "" "")
10927         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10928               (match_operand 2 "" "g,g")))
10929    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10930    (use (match_operand:SI 4 "register_operand" "r,r"))
10931    (clobber (reg:SI LR_REGNO))]
10932   "(DEFAULT_ABI == ABI_V4
10933     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10934     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10936   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10937     output_asm_insn ("crxor 6,6,6", operands);
10939   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10940     output_asm_insn ("creqv 6,6,6", operands);
10942   if (flag_pic == 2)
10943     return "bl %z1+32768@plt";
10944   else
10945     return "bl %z1@plt";
10947   [(set_attr "type" "branch,branch")
10948    (set_attr "length" "4,8")])
10951 ;; Call to AIX abi function in the same module.
10953 (define_insn "*call_local_aix<mode>"
10954   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10955          (match_operand 1 "" "g"))
10956    (clobber (reg:P LR_REGNO))]
10957   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10958   "bl %z0"
10959   [(set_attr "type" "branch")
10960    (set_attr "length" "4")])
10962 (define_insn "*call_value_local_aix<mode>"
10963   [(set (match_operand 0 "" "")
10964         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10965               (match_operand 2 "" "g")))
10966    (clobber (reg:P LR_REGNO))]
10967   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10968   "bl %z1"
10969   [(set_attr "type" "branch")
10970    (set_attr "length" "4")])
10972 ;; Call to AIX abi function which may be in another module.
10973 ;; Restore the TOC pointer (r2) after the call.
10975 (define_insn "*call_nonlocal_aix<mode>"
10976   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10977          (match_operand 1 "" "g"))
10978    (clobber (reg:P LR_REGNO))]
10979   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10980   "bl %z0\;nop"
10981   [(set_attr "type" "branch")
10982    (set_attr "length" "8")])
10984 (define_insn "*call_value_nonlocal_aix<mode>"
10985   [(set (match_operand 0 "" "")
10986         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10987               (match_operand 2 "" "g")))
10988    (clobber (reg:P LR_REGNO))]
10989   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10990   "bl %z1\;nop"
10991   [(set_attr "type" "branch")
10992    (set_attr "length" "8")])
10994 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10995 ;; Operand0 is the addresss of the function to call
10996 ;; Operand2 is the location in the function descriptor to load r2 from
10997 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10999 (define_insn "*call_indirect_aix<mode>"
11000   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11001          (match_operand 1 "" "g,g"))
11002    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11003    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11004    (clobber (reg:P LR_REGNO))]
11005   "DEFAULT_ABI == ABI_AIX"
11006   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11007   [(set_attr "type" "jmpreg")
11008    (set_attr "length" "12")])
11010 (define_insn "*call_value_indirect_aix<mode>"
11011   [(set (match_operand 0 "" "")
11012         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11013               (match_operand 2 "" "g,g")))
11014    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11015    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11016    (clobber (reg:P LR_REGNO))]
11017   "DEFAULT_ABI == ABI_AIX"
11018   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11019   [(set_attr "type" "jmpreg")
11020    (set_attr "length" "12")])
11022 ;; Call to indirect functions with the ELFv2 ABI.
11023 ;; Operand0 is the addresss of the function to call
11024 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11026 (define_insn "*call_indirect_elfv2<mode>"
11027   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11028          (match_operand 1 "" "g,g"))
11029    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11030    (clobber (reg:P LR_REGNO))]
11031   "DEFAULT_ABI == ABI_ELFv2"
11032   "b%T0l\;<ptrload> 2,%2(1)"
11033   [(set_attr "type" "jmpreg")
11034    (set_attr "length" "8")])
11036 (define_insn "*call_value_indirect_elfv2<mode>"
11037   [(set (match_operand 0 "" "")
11038         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11039               (match_operand 2 "" "g,g")))
11040    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11041    (clobber (reg:P LR_REGNO))]
11042   "DEFAULT_ABI == ABI_ELFv2"
11043   "b%T1l\;<ptrload> 2,%3(1)"
11044   [(set_attr "type" "jmpreg")
11045    (set_attr "length" "8")])
11048 ;; Call subroutine returning any type.
11049 (define_expand "untyped_call"
11050   [(parallel [(call (match_operand 0 "" "")
11051                     (const_int 0))
11052               (match_operand 1 "" "")
11053               (match_operand 2 "" "")])]
11054   ""
11055   "
11057   int i;
11059   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11061   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11062     {
11063       rtx set = XVECEXP (operands[2], 0, i);
11064       emit_move_insn (SET_DEST (set), SET_SRC (set));
11065     }
11067   /* The optimizer does not know that the call sets the function value
11068      registers we stored in the result block.  We avoid problems by
11069      claiming that all hard registers are used and clobbered at this
11070      point.  */
11071   emit_insn (gen_blockage ());
11073   DONE;
11076 ;; sibling call patterns
11077 (define_expand "sibcall"
11078   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11079                     (match_operand 1 "" ""))
11080               (use (match_operand 2 "" ""))
11081               (simple_return)])]
11082   ""
11083   "
11085 #if TARGET_MACHO
11086   if (MACHOPIC_INDIRECT)
11087     operands[0] = machopic_indirect_call_target (operands[0]);
11088 #endif
11090   gcc_assert (GET_CODE (operands[0]) == MEM);
11091   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11093   operands[0] = XEXP (operands[0], 0);
11095   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11096     {
11097       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11098       DONE;
11099     }
11102 (define_expand "sibcall_value"
11103   [(parallel [(set (match_operand 0 "register_operand" "")
11104                 (call (mem:SI (match_operand 1 "address_operand" ""))
11105                       (match_operand 2 "" "")))
11106               (use (match_operand 3 "" ""))
11107               (simple_return)])]
11108   ""
11109   "
11111 #if TARGET_MACHO
11112   if (MACHOPIC_INDIRECT)
11113     operands[1] = machopic_indirect_call_target (operands[1]);
11114 #endif
11116   gcc_assert (GET_CODE (operands[1]) == MEM);
11117   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11119   operands[1] = XEXP (operands[1], 0);
11121   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11122     {
11123       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11124       DONE;
11125     }
11128 (define_insn "*sibcall_local32"
11129   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11130          (match_operand 1 "" "g,g"))
11131    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11132    (simple_return)]
11133   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11134   "*
11136   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11137     output_asm_insn (\"crxor 6,6,6\", operands);
11139   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11140     output_asm_insn (\"creqv 6,6,6\", operands);
11142   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11144   [(set_attr "type" "branch")
11145    (set_attr "length" "4,8")])
11147 (define_insn "*sibcall_local64"
11148   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11149          (match_operand 1 "" "g,g"))
11150    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11151    (simple_return)]
11152   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11153   "*
11155   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11156     output_asm_insn (\"crxor 6,6,6\", operands);
11158   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11159     output_asm_insn (\"creqv 6,6,6\", operands);
11161   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11163   [(set_attr "type" "branch")
11164    (set_attr "length" "4,8")])
11166 (define_insn "*sibcall_value_local32"
11167   [(set (match_operand 0 "" "")
11168         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11169               (match_operand 2 "" "g,g")))
11170    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11171    (simple_return)]
11172   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11173   "*
11175   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11176     output_asm_insn (\"crxor 6,6,6\", operands);
11178   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11179     output_asm_insn (\"creqv 6,6,6\", operands);
11181   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11183   [(set_attr "type" "branch")
11184    (set_attr "length" "4,8")])
11186 (define_insn "*sibcall_value_local64"
11187   [(set (match_operand 0 "" "")
11188         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11189               (match_operand 2 "" "g,g")))
11190    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11191    (simple_return)]
11192   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11193   "*
11195   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11196     output_asm_insn (\"crxor 6,6,6\", operands);
11198   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11199     output_asm_insn (\"creqv 6,6,6\", operands);
11201   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11203   [(set_attr "type" "branch")
11204    (set_attr "length" "4,8")])
11206 (define_insn "*sibcall_nonlocal_sysv<mode>"
11207   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11208          (match_operand 1 "" ""))
11209    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11210    (simple_return)]
11211   "(DEFAULT_ABI == ABI_DARWIN
11212     || DEFAULT_ABI == ABI_V4)
11213    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11214   "*
11216   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11217     output_asm_insn (\"crxor 6,6,6\", operands);
11219   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11220     output_asm_insn (\"creqv 6,6,6\", operands);
11222   if (which_alternative >= 2)
11223     return \"b%T0\";
11224   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11225     {
11226       gcc_assert (!TARGET_SECURE_PLT);
11227       return \"b %z0@plt\";
11228     }
11229   else
11230     return \"b %z0\";
11232   [(set_attr "type" "branch")
11233    (set_attr "length" "4,8,4,8")])
11235 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11236   [(set (match_operand 0 "" "")
11237         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11238               (match_operand 2 "" "")))
11239    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11240    (simple_return)]
11241   "(DEFAULT_ABI == ABI_DARWIN
11242     || DEFAULT_ABI == ABI_V4)
11243    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11244   "*
11246   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11247     output_asm_insn (\"crxor 6,6,6\", operands);
11249   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11250     output_asm_insn (\"creqv 6,6,6\", operands);
11252   if (which_alternative >= 2)
11253     return \"b%T1\";
11254   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11255     {
11256       gcc_assert (!TARGET_SECURE_PLT);
11257       return \"b %z1@plt\";
11258     }
11259   else
11260     return \"b %z1\";
11262   [(set_attr "type" "branch")
11263    (set_attr "length" "4,8,4,8")])
11265 ;; AIX ABI sibling call patterns.
11267 (define_insn "*sibcall_aix<mode>"
11268   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11269          (match_operand 1 "" "g,g"))
11270    (simple_return)]
11271   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11272   "@
11273    b %z0
11274    b%T0"
11275   [(set_attr "type" "branch")
11276    (set_attr "length" "4")])
11278 (define_insn "*sibcall_value_aix<mode>"
11279   [(set (match_operand 0 "" "")
11280         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11281               (match_operand 2 "" "g,g")))
11282    (simple_return)]
11283   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11284   "@
11285    b %z1
11286    b%T1"
11287   [(set_attr "type" "branch")
11288    (set_attr "length" "4")])
11290 (define_expand "sibcall_epilogue"
11291   [(use (const_int 0))]
11292   ""
11294   if (!TARGET_SCHED_PROLOG)
11295     emit_insn (gen_blockage ());
11296   rs6000_emit_epilogue (TRUE);
11297   DONE;
11300 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11301 ;; all of memory.  This blocks insns from being moved across this point.
11303 (define_insn "blockage"
11304   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11305   ""
11306   "")
11308 (define_expand "probe_stack_address"
11309   [(use (match_operand 0 "address_operand"))]
11310   ""
11312   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11313   MEM_VOLATILE_P (operands[0]) = 1;
11315   if (TARGET_64BIT)
11316     emit_insn (gen_probe_stack_di (operands[0]));
11317   else
11318     emit_insn (gen_probe_stack_si (operands[0]));
11319   DONE;
11322 (define_insn "probe_stack_<mode>"
11323   [(set (match_operand:P 0 "memory_operand" "=m")
11324         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11325   ""
11327   operands[1] = gen_rtx_REG (Pmode, 0);
11328   return "st<wd>%U0%X0 %1,%0";
11330   [(set_attr "type" "store")
11331    (set (attr "update")
11332         (if_then_else (match_operand 0 "update_address_mem")
11333                       (const_string "yes")
11334                       (const_string "no")))
11335    (set (attr "indexed")
11336         (if_then_else (match_operand 0 "indexed_address_mem")
11337                       (const_string "yes")
11338                       (const_string "no")))
11339    (set_attr "length" "4")])
11341 (define_insn "probe_stack_range<P:mode>"
11342   [(set (match_operand:P 0 "register_operand" "=r")
11343         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11344                             (match_operand:P 2 "register_operand" "r")]
11345                            UNSPECV_PROBE_STACK_RANGE))]
11346   ""
11347   "* return output_probe_stack_range (operands[0], operands[2]);"
11348   [(set_attr "type" "three")])
11350 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11351 ;; signed & unsigned, and one type of branch.
11353 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11354 ;; insns, and branches.
11356 (define_expand "cbranch<mode>4"
11357   [(use (match_operator 0 "rs6000_cbranch_operator"
11358          [(match_operand:GPR 1 "gpc_reg_operand" "")
11359           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11360    (use (match_operand 3 ""))]
11361   ""
11362   "
11364   /* Take care of the possibility that operands[2] might be negative but
11365      this might be a logical operation.  That insn doesn't exist.  */
11366   if (GET_CODE (operands[2]) == CONST_INT
11367       && INTVAL (operands[2]) < 0)
11368     {
11369       operands[2] = force_reg (<MODE>mode, operands[2]);
11370       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11371                                     GET_MODE (operands[0]),
11372                                     operands[1], operands[2]);
11373    }
11375   rs6000_emit_cbranch (<MODE>mode, operands);
11376   DONE;
11379 (define_expand "cbranch<mode>4"
11380   [(use (match_operator 0 "rs6000_cbranch_operator"
11381          [(match_operand:FP 1 "gpc_reg_operand" "")
11382           (match_operand:FP 2 "gpc_reg_operand" "")]))
11383    (use (match_operand 3 ""))]
11384   ""
11385   "
11387   rs6000_emit_cbranch (<MODE>mode, operands);
11388   DONE;
11391 (define_expand "cstore<mode>4_signed"
11392   [(use (match_operator 1 "signed_comparison_operator"
11393          [(match_operand:P 2 "gpc_reg_operand")
11394           (match_operand:P 3 "gpc_reg_operand")]))
11395    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11396   ""
11398   enum rtx_code cond_code = GET_CODE (operands[1]);
11400   rtx op0 = operands[0];
11401   rtx op1 = operands[2];
11402   rtx op2 = operands[3];
11404   if (cond_code == GE || cond_code == LT)
11405     {
11406       cond_code = swap_condition (cond_code);
11407       std::swap (op1, op2);
11408     }
11410   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11411   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11412   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11414   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11415   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11416   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11418   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11420   if (cond_code == LE)
11421     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11422   else
11423     {
11424       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11425       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11426       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11427     }
11429   DONE;
11432 (define_expand "cstore<mode>4_unsigned"
11433   [(use (match_operator 1 "unsigned_comparison_operator"
11434          [(match_operand:P 2 "gpc_reg_operand")
11435           (match_operand:P 3 "reg_or_short_operand")]))
11436    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11437   ""
11439   enum rtx_code cond_code = GET_CODE (operands[1]);
11441   rtx op0 = operands[0];
11442   rtx op1 = operands[2];
11443   rtx op2 = operands[3];
11445   if (cond_code == GEU || cond_code == LTU)
11446     {
11447       cond_code = swap_condition (cond_code);
11448       std::swap (op1, op2);
11449     }
11451   if (!gpc_reg_operand (op1, <MODE>mode))
11452     op1 = force_reg (<MODE>mode, op1);
11453   if (!reg_or_short_operand (op2, <MODE>mode))
11454     op2 = force_reg (<MODE>mode, op2);
11456   rtx tmp = gen_reg_rtx (<MODE>mode);
11457   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11459   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11460   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11462   if (cond_code == LEU)
11463     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11464   else
11465     emit_insn (gen_neg<mode>2 (op0, tmp2));
11467   DONE;
11470 (define_expand "cstore_si_as_di"
11471   [(use (match_operator 1 "unsigned_comparison_operator"
11472          [(match_operand:SI 2 "gpc_reg_operand")
11473           (match_operand:SI 3 "reg_or_short_operand")]))
11474    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11475   ""
11477   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11478   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11480   operands[2] = force_reg (SImode, operands[2]);
11481   operands[3] = force_reg (SImode, operands[3]);
11482   rtx op1 = gen_reg_rtx (DImode);
11483   rtx op2 = gen_reg_rtx (DImode);
11484   convert_move (op1, operands[2], uns_flag);
11485   convert_move (op2, operands[3], uns_flag);
11487   if (cond_code == GT || cond_code == LE)
11488     {
11489       cond_code = swap_condition (cond_code);
11490       std::swap (op1, op2);
11491     }
11493   rtx tmp = gen_reg_rtx (DImode);
11494   rtx tmp2 = gen_reg_rtx (DImode);
11495   emit_insn (gen_subdi3 (tmp, op1, op2));
11496   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11498   rtx tmp3;
11499   switch (cond_code)
11500     {
11501     default:
11502       gcc_unreachable ();
11503     case LT:
11504       tmp3 = tmp2;
11505       break;
11506     case GE:
11507       tmp3 = gen_reg_rtx (DImode);
11508       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11509       break;
11510     }
11512   convert_move (operands[0], tmp3, 1);
11514   DONE;
11517 (define_expand "cstore<mode>4_signed_imm"
11518   [(use (match_operator 1 "signed_comparison_operator"
11519          [(match_operand:GPR 2 "gpc_reg_operand")
11520           (match_operand:GPR 3 "immediate_operand")]))
11521    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11522   ""
11524   bool invert = false;
11526   enum rtx_code cond_code = GET_CODE (operands[1]);
11528   rtx op0 = operands[0];
11529   rtx op1 = operands[2];
11530   HOST_WIDE_INT val = INTVAL (operands[3]);
11532   if (cond_code == GE || cond_code == GT)
11533     {
11534       cond_code = reverse_condition (cond_code);
11535       invert = true;
11536     }
11538   if (cond_code == LE)
11539     val++;
11541   rtx tmp = gen_reg_rtx (<MODE>mode);
11542   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11543   rtx x = gen_reg_rtx (<MODE>mode);
11544   if (val < 0)
11545     emit_insn (gen_and<mode>3 (x, op1, tmp));
11546   else
11547     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11549   if (invert)
11550     {
11551       rtx tmp = gen_reg_rtx (<MODE>mode);
11552       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11553       x = tmp;
11554     }
11556   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11557   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11559   DONE;
11562 (define_expand "cstore<mode>4_unsigned_imm"
11563   [(use (match_operator 1 "unsigned_comparison_operator"
11564          [(match_operand:GPR 2 "gpc_reg_operand")
11565           (match_operand:GPR 3 "immediate_operand")]))
11566    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11567   ""
11569   bool invert = false;
11571   enum rtx_code cond_code = GET_CODE (operands[1]);
11573   rtx op0 = operands[0];
11574   rtx op1 = operands[2];
11575   HOST_WIDE_INT val = INTVAL (operands[3]);
11577   if (cond_code == GEU || cond_code == GTU)
11578     {
11579       cond_code = reverse_condition (cond_code);
11580       invert = true;
11581     }
11583   if (cond_code == LEU)
11584     val++;
11586   rtx tmp = gen_reg_rtx (<MODE>mode);
11587   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11588   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11589   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11590   rtx x = gen_reg_rtx (<MODE>mode);
11591   if (val < 0)
11592     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11593   else
11594     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11596   if (invert)
11597     {
11598       rtx tmp = gen_reg_rtx (<MODE>mode);
11599       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11600       x = tmp;
11601     }
11603   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11604   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11606   DONE;
11609 (define_expand "cstore<mode>4"
11610   [(use (match_operator 1 "rs6000_cbranch_operator"
11611          [(match_operand:GPR 2 "gpc_reg_operand")
11612           (match_operand:GPR 3 "reg_or_short_operand")]))
11613    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11614   ""
11616   /* Use ISEL if the user asked for it.  */
11617   if (TARGET_ISEL)
11618     rs6000_emit_sISEL (<MODE>mode, operands);
11620   /* Expanding EQ and NE directly to some machine instructions does not help
11621      but does hurt combine.  So don't.  */
11622   else if (GET_CODE (operands[1]) == EQ)
11623     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11624   else if (<MODE>mode == Pmode
11625            && GET_CODE (operands[1]) == NE)
11626     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11627   else if (GET_CODE (operands[1]) == NE)
11628     {
11629       rtx tmp = gen_reg_rtx (<MODE>mode);
11630       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11631       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11632     }
11634   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11635      etc. combinations magically work out just right.  */
11636   else if (<MODE>mode == Pmode
11637            && unsigned_comparison_operator (operands[1], VOIDmode))
11638     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11639                                            operands[2], operands[3]));
11641   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11642   else if (<MODE>mode == SImode && Pmode == DImode)
11643     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11644                                     operands[2], operands[3]));
11646   /* For signed comparisons against a constant, we can do some simple
11647      bit-twiddling.  */
11648   else if (signed_comparison_operator (operands[1], VOIDmode)
11649            && CONST_INT_P (operands[3]))
11650     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11651                                              operands[2], operands[3]));
11653   /* And similarly for unsigned comparisons.  */
11654   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11655            && CONST_INT_P (operands[3]))
11656     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11657                                                operands[2], operands[3]));
11659   /* We also do not want to use mfcr for signed comparisons.  */
11660   else if (<MODE>mode == Pmode
11661            && signed_comparison_operator (operands[1], VOIDmode))
11662     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11663                                          operands[2], operands[3]));
11665   /* Everything else, use the mfcr brute force.  */
11666   else
11667     rs6000_emit_sCOND (<MODE>mode, operands);
11669   DONE;
11672 (define_expand "cstore<mode>4"
11673   [(use (match_operator 1 "rs6000_cbranch_operator"
11674          [(match_operand:FP 2 "gpc_reg_operand")
11675           (match_operand:FP 3 "gpc_reg_operand")]))
11676    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11677   ""
11679   rs6000_emit_sCOND (<MODE>mode, operands);
11680   DONE;
11684 (define_expand "stack_protect_set"
11685   [(match_operand 0 "memory_operand" "")
11686    (match_operand 1 "memory_operand" "")]
11687   ""
11689 #ifdef TARGET_THREAD_SSP_OFFSET
11690   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11691   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11692   operands[1] = gen_rtx_MEM (Pmode, addr);
11693 #endif
11694   if (TARGET_64BIT)
11695     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11696   else
11697     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11698   DONE;
11701 (define_insn "stack_protect_setsi"
11702   [(set (match_operand:SI 0 "memory_operand" "=m")
11703         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11704    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11705   "TARGET_32BIT"
11706   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11707   [(set_attr "type" "three")
11708    (set_attr "length" "12")])
11710 (define_insn "stack_protect_setdi"
11711   [(set (match_operand:DI 0 "memory_operand" "=Y")
11712         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11713    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11714   "TARGET_64BIT"
11715   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11716   [(set_attr "type" "three")
11717    (set_attr "length" "12")])
11719 (define_expand "stack_protect_test"
11720   [(match_operand 0 "memory_operand" "")
11721    (match_operand 1 "memory_operand" "")
11722    (match_operand 2 "" "")]
11723   ""
11725   rtx test, op0, op1;
11726 #ifdef TARGET_THREAD_SSP_OFFSET
11727   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11728   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11729   operands[1] = gen_rtx_MEM (Pmode, addr);
11730 #endif
11731   op0 = operands[0];
11732   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11733   test = gen_rtx_EQ (VOIDmode, op0, op1);
11734   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11735   DONE;
11738 (define_insn "stack_protect_testsi"
11739   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11740         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11741                       (match_operand:SI 2 "memory_operand" "m,m")]
11742                      UNSPEC_SP_TEST))
11743    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11744    (clobber (match_scratch:SI 3 "=&r,&r"))]
11745   "TARGET_32BIT"
11746   "@
11747    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11748    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11749   [(set_attr "length" "16,20")])
11751 (define_insn "stack_protect_testdi"
11752   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11753         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11754                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11755                      UNSPEC_SP_TEST))
11756    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11757    (clobber (match_scratch:DI 3 "=&r,&r"))]
11758   "TARGET_64BIT"
11759   "@
11760    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11761    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11762   [(set_attr "length" "16,20")])
11765 ;; Here are the actual compare insns.
11766 (define_insn "*cmp<mode>_signed"
11767   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11768         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11769                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11770   ""
11771   "cmp<wd>%I2 %0,%1,%2"
11772   [(set_attr "type" "cmp")])
11774 (define_insn "*cmp<mode>_unsigned"
11775   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11776         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11777                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11778   ""
11779   "cmpl<wd>%I2 %0,%1,%2"
11780   [(set_attr "type" "cmp")])
11782 ;; If we are comparing a register for equality with a large constant,
11783 ;; we can do this with an XOR followed by a compare.  But this is profitable
11784 ;; only if the large constant is only used for the comparison (and in this
11785 ;; case we already have a register to reuse as scratch).
11787 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11788 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11790 (define_peephole2
11791   [(set (match_operand:SI 0 "register_operand")
11792         (match_operand:SI 1 "logical_const_operand" ""))
11793    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11794                        [(match_dup 0)
11795                         (match_operand:SI 2 "logical_const_operand" "")]))
11796    (set (match_operand:CC 4 "cc_reg_operand" "")
11797         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11798                     (match_dup 0)))
11799    (set (pc)
11800         (if_then_else (match_operator 6 "equality_operator"
11801                        [(match_dup 4) (const_int 0)])
11802                       (match_operand 7 "" "")
11803                       (match_operand 8 "" "")))]
11804   "peep2_reg_dead_p (3, operands[0])
11805    && peep2_reg_dead_p (4, operands[4])
11806    && REGNO (operands[0]) != REGNO (operands[5])"
11807  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11808   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11809   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11812   /* Get the constant we are comparing against, and see what it looks like
11813      when sign-extended from 16 to 32 bits.  Then see what constant we could
11814      XOR with SEXTC to get the sign-extended value.  */
11815   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11816                                               SImode,
11817                                               operands[1], operands[2]);
11818   HOST_WIDE_INT c = INTVAL (cnst);
11819   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11820   HOST_WIDE_INT xorv = c ^ sextc;
11822   operands[9] = GEN_INT (xorv);
11823   operands[10] = GEN_INT (sextc);
11826 ;; The following two insns don't exist as single insns, but if we provide
11827 ;; them, we can swap an add and compare, which will enable us to overlap more
11828 ;; of the required delay between a compare and branch.  We generate code for
11829 ;; them by splitting.
11831 (define_insn ""
11832   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11833         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11834                     (match_operand:SI 2 "short_cint_operand" "i")))
11835    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11836         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11837   ""
11838   "#"
11839   [(set_attr "length" "8")])
11841 (define_insn ""
11842   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11843         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11844                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11845    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11846         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11847   ""
11848   "#"
11849   [(set_attr "length" "8")])
11851 (define_split
11852   [(set (match_operand:CC 3 "cc_reg_operand" "")
11853         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11854                     (match_operand:SI 2 "short_cint_operand" "")))
11855    (set (match_operand:SI 0 "gpc_reg_operand" "")
11856         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11857   ""
11858   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11859    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11861 (define_split
11862   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11863         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11864                        (match_operand:SI 2 "u_short_cint_operand" "")))
11865    (set (match_operand:SI 0 "gpc_reg_operand" "")
11866         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11867   ""
11868   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11869    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11871 ;; Only need to compare second words if first words equal
11872 (define_insn "*cmp<mode>_internal1"
11873   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11874         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11875                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11876   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11877    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11878   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11879   [(set_attr "type" "fpcompare")
11880    (set_attr "length" "12")])
11882 (define_insn_and_split "*cmp<mode>_internal2"
11883   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11884         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11885                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11886     (clobber (match_scratch:DF 3 "=d"))
11887     (clobber (match_scratch:DF 4 "=d"))
11888     (clobber (match_scratch:DF 5 "=d"))
11889     (clobber (match_scratch:DF 6 "=d"))
11890     (clobber (match_scratch:DF 7 "=d"))
11891     (clobber (match_scratch:DF 8 "=d"))
11892     (clobber (match_scratch:DF 9 "=d"))
11893     (clobber (match_scratch:DF 10 "=d"))
11894     (clobber (match_scratch:GPR 11 "=b"))]
11895   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11896    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11897   "#"
11898   "&& reload_completed"
11899   [(set (match_dup 3) (match_dup 14))
11900    (set (match_dup 4) (match_dup 15))
11901    (set (match_dup 9) (abs:DF (match_dup 5)))
11902    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11903    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11904                            (label_ref (match_dup 12))
11905                            (pc)))
11906    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11907    (set (pc) (label_ref (match_dup 13)))
11908    (match_dup 12)
11909    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11910    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11911    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11912    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11913    (match_dup 13)]
11915   REAL_VALUE_TYPE rv;
11916   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11917   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11919   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11920   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11921   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11922   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11923   operands[12] = gen_label_rtx ();
11924   operands[13] = gen_label_rtx ();
11925   real_inf (&rv);
11926   operands[14] = force_const_mem (DFmode,
11927                                   const_double_from_real_value (rv, DFmode));
11928   operands[15] = force_const_mem (DFmode,
11929                                   const_double_from_real_value (dconst0,
11930                                                                 DFmode));
11931   if (TARGET_TOC)
11932     {
11933       rtx tocref;
11934       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11935       operands[14] = gen_const_mem (DFmode, tocref);
11936       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11937       operands[15] = gen_const_mem (DFmode, tocref);
11938       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11939       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11940     }
11943 ;; Now we have the scc insns.  We can do some combinations because of the
11944 ;; way the machine works.
11946 ;; Note that this is probably faster if we can put an insn between the
11947 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11948 ;; cases the insns below which don't use an intermediate CR field will
11949 ;; be used instead.
11950 (define_insn ""
11951   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11952         (match_operator:SI 1 "scc_comparison_operator"
11953                            [(match_operand 2 "cc_reg_operand" "y")
11954                             (const_int 0)]))]
11955   ""
11956   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11957   [(set (attr "type")
11958      (cond [(match_test "TARGET_MFCRF")
11959                 (const_string "mfcrf")
11960            ]
11961         (const_string "mfcr")))
11962    (set_attr "length" "8")])
11964 ;; Same as above, but get the GT bit.
11965 (define_insn "move_from_CR_gt_bit"
11966   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11967         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11968   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11969   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11970   [(set_attr "type" "mfcr")
11971    (set_attr "length" "8")])
11973 ;; Same as above, but get the OV/ORDERED bit.
11974 (define_insn "move_from_CR_ov_bit"
11975   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11976         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11977                    UNSPEC_MV_CR_OV))]
11978   "TARGET_ISEL"
11979   "mfcr %0\;rlwinm %0,%0,%t1,1"
11980   [(set_attr "type" "mfcr")
11981    (set_attr "length" "8")])
11983 (define_insn ""
11984   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11985         (match_operator:DI 1 "scc_comparison_operator"
11986                            [(match_operand 2 "cc_reg_operand" "y")
11987                             (const_int 0)]))]
11988   "TARGET_POWERPC64"
11989   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11990   [(set (attr "type")
11991      (cond [(match_test "TARGET_MFCRF")
11992                 (const_string "mfcrf")
11993            ]
11994         (const_string "mfcr")))
11995    (set_attr "length" "8")])
11997 (define_insn ""
11998   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11999         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12000                                        [(match_operand 2 "cc_reg_operand" "y,y")
12001                                         (const_int 0)])
12002                     (const_int 0)))
12003    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12004         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12005   "TARGET_32BIT"
12006   "@
12007    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12008    #"
12009   [(set_attr "type" "shift")
12010    (set_attr "dot" "yes")
12011    (set_attr "length" "8,16")])
12013 (define_split
12014   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12015         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12016                                        [(match_operand 2 "cc_reg_operand" "")
12017                                         (const_int 0)])
12018                     (const_int 0)))
12019    (set (match_operand:SI 3 "gpc_reg_operand" "")
12020         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12021   "TARGET_32BIT && reload_completed"
12022   [(set (match_dup 3)
12023         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12024    (set (match_dup 0)
12025         (compare:CC (match_dup 3)
12026                     (const_int 0)))]
12027   "")
12029 (define_insn ""
12030   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12031         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12032                                       [(match_operand 2 "cc_reg_operand" "y")
12033                                        (const_int 0)])
12034                    (match_operand:SI 3 "const_int_operand" "n")))]
12035   ""
12036   "*
12038   int is_bit = ccr_bit (operands[1], 1);
12039   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12040   int count;
12042   if (is_bit >= put_bit)
12043     count = is_bit - put_bit;
12044   else
12045     count = 32 - (put_bit - is_bit);
12047   operands[4] = GEN_INT (count);
12048   operands[5] = GEN_INT (put_bit);
12050   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12052   [(set (attr "type")
12053      (cond [(match_test "TARGET_MFCRF")
12054                 (const_string "mfcrf")
12055            ]
12056         (const_string "mfcr")))
12057    (set_attr "length" "8")])
12059 (define_insn ""
12060   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12061         (compare:CC
12062          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12063                                        [(match_operand 2 "cc_reg_operand" "y,y")
12064                                         (const_int 0)])
12065                     (match_operand:SI 3 "const_int_operand" "n,n"))
12066          (const_int 0)))
12067    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12068         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12069                    (match_dup 3)))]
12070   ""
12071   "*
12073   int is_bit = ccr_bit (operands[1], 1);
12074   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12075   int count;
12077   /* Force split for non-cc0 compare.  */
12078   if (which_alternative == 1)
12079      return \"#\";
12081   if (is_bit >= put_bit)
12082     count = is_bit - put_bit;
12083   else
12084     count = 32 - (put_bit - is_bit);
12086   operands[5] = GEN_INT (count);
12087   operands[6] = GEN_INT (put_bit);
12089   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12091   [(set_attr "type" "shift")
12092    (set_attr "dot" "yes")
12093    (set_attr "length" "8,16")])
12095 (define_split
12096   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12097         (compare:CC
12098          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12099                                        [(match_operand 2 "cc_reg_operand" "")
12100                                         (const_int 0)])
12101                     (match_operand:SI 3 "const_int_operand" ""))
12102          (const_int 0)))
12103    (set (match_operand:SI 4 "gpc_reg_operand" "")
12104         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12105                    (match_dup 3)))]
12106   "reload_completed"
12107   [(set (match_dup 4)
12108         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12109                    (match_dup 3)))
12110    (set (match_dup 0)
12111         (compare:CC (match_dup 4)
12112                     (const_int 0)))]
12113   "")
12116 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12117                               (DI "rKJI")])
12119 (define_insn_and_split "eq<mode>3"
12120   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12121         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12122                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12123    (clobber (match_scratch:GPR 3 "=r"))
12124    (clobber (match_scratch:GPR 4 "=r"))]
12125   ""
12126   "#"
12127   ""
12128   [(set (match_dup 4)
12129         (clz:GPR (match_dup 3)))
12130    (set (match_dup 0)
12131         (lshiftrt:GPR (match_dup 4)
12132                       (match_dup 5)))]
12134   operands[3] = rs6000_emit_eqne (<MODE>mode,
12135                                   operands[1], operands[2], operands[3]);
12137   if (GET_CODE (operands[4]) == SCRATCH)
12138     operands[4] = gen_reg_rtx (<MODE>mode);
12140   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12142   [(set (attr "length")
12143         (if_then_else (match_test "operands[2] == const0_rtx")
12144                       (const_string "8")
12145                       (const_string "12")))])
12147 (define_insn_and_split "ne<mode>3"
12148   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12149         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12150               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12151    (clobber (match_scratch:P 3 "=r"))
12152    (clobber (match_scratch:P 4 "=r"))
12153    (clobber (reg:P CA_REGNO))]
12154   "!TARGET_ISEL"
12155   "#"
12156   ""
12157   [(parallel [(set (match_dup 4)
12158                    (plus:P (match_dup 3)
12159                            (const_int -1)))
12160               (set (reg:P CA_REGNO)
12161                    (ne:P (match_dup 3)
12162                          (const_int 0)))])
12163    (parallel [(set (match_dup 0)
12164                    (plus:P (plus:P (not:P (match_dup 4))
12165                                    (reg:P CA_REGNO))
12166                            (match_dup 3)))
12167               (clobber (reg:P CA_REGNO))])]
12169   operands[3] = rs6000_emit_eqne (<MODE>mode,
12170                                   operands[1], operands[2], operands[3]);
12172   if (GET_CODE (operands[4]) == SCRATCH)
12173     operands[4] = gen_reg_rtx (<MODE>mode);
12175   [(set (attr "length")
12176         (if_then_else (match_test "operands[2] == const0_rtx")
12177                       (const_string "8")
12178                       (const_string "12")))])
12180 (define_insn_and_split "*neg_eq_<mode>"
12181   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12182         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12183                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12184    (clobber (match_scratch:P 3 "=r"))
12185    (clobber (match_scratch:P 4 "=r"))
12186    (clobber (reg:P CA_REGNO))]
12187   ""
12188   "#"
12189   ""
12190   [(parallel [(set (match_dup 4)
12191                    (plus:P (match_dup 3)
12192                            (const_int -1)))
12193               (set (reg:P CA_REGNO)
12194                    (ne:P (match_dup 3)
12195                          (const_int 0)))])
12196    (parallel [(set (match_dup 0)
12197                    (plus:P (reg:P CA_REGNO)
12198                            (const_int -1)))
12199               (clobber (reg:P CA_REGNO))])]
12201   operands[3] = rs6000_emit_eqne (<MODE>mode,
12202                                   operands[1], operands[2], operands[3]);
12204   if (GET_CODE (operands[4]) == SCRATCH)
12205     operands[4] = gen_reg_rtx (<MODE>mode);
12207   [(set (attr "length")
12208         (if_then_else (match_test "operands[2] == const0_rtx")
12209                       (const_string "8")
12210                       (const_string "12")))])
12212 (define_insn_and_split "*neg_ne_<mode>"
12213   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12214         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12215                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12216    (clobber (match_scratch:P 3 "=r"))
12217    (clobber (match_scratch:P 4 "=r"))
12218    (clobber (reg:P CA_REGNO))]
12219   ""
12220   "#"
12221   ""
12222   [(parallel [(set (match_dup 4)
12223                    (neg:P (match_dup 3)))
12224               (set (reg:P CA_REGNO)
12225                    (eq:P (match_dup 3)
12226                          (const_int 0)))])
12227    (parallel [(set (match_dup 0)
12228                    (plus:P (reg:P CA_REGNO)
12229                            (const_int -1)))
12230               (clobber (reg:P CA_REGNO))])]
12232   operands[3] = rs6000_emit_eqne (<MODE>mode,
12233                                   operands[1], operands[2], operands[3]);
12235   if (GET_CODE (operands[4]) == SCRATCH)
12236     operands[4] = gen_reg_rtx (<MODE>mode);
12238   [(set (attr "length")
12239         (if_then_else (match_test "operands[2] == const0_rtx")
12240                       (const_string "8")
12241                       (const_string "12")))])
12243 (define_insn_and_split "*plus_eq_<mode>"
12244   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12245         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12246                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12247                 (match_operand:P 3 "gpc_reg_operand" "r")))
12248    (clobber (match_scratch:P 4 "=r"))
12249    (clobber (match_scratch:P 5 "=r"))
12250    (clobber (reg:P CA_REGNO))]
12251   ""
12252   "#"
12253   ""
12254   [(parallel [(set (match_dup 5)
12255                    (neg:P (match_dup 4)))
12256               (set (reg:P CA_REGNO)
12257                    (eq:P (match_dup 4)
12258                          (const_int 0)))])
12259    (parallel [(set (match_dup 0)
12260                    (plus:P (match_dup 3)
12261                            (reg:P CA_REGNO)))
12262               (clobber (reg:P CA_REGNO))])]
12264   operands[4] = rs6000_emit_eqne (<MODE>mode,
12265                                   operands[1], operands[2], operands[4]);
12267   if (GET_CODE (operands[5]) == SCRATCH)
12268     operands[5] = gen_reg_rtx (<MODE>mode);
12270   [(set (attr "length")
12271         (if_then_else (match_test "operands[2] == const0_rtx")
12272                       (const_string "8")
12273                       (const_string "12")))])
12275 (define_insn_and_split "*plus_ne_<mode>"
12276   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12277         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12278                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12279                 (match_operand:P 3 "gpc_reg_operand" "r")))
12280    (clobber (match_scratch:P 4 "=r"))
12281    (clobber (match_scratch:P 5 "=r"))
12282    (clobber (reg:P CA_REGNO))]
12283   ""
12284   "#"
12285   ""
12286   [(parallel [(set (match_dup 5)
12287                    (plus:P (match_dup 4)
12288                            (const_int -1)))
12289               (set (reg:P CA_REGNO)
12290                    (ne:P (match_dup 4)
12291                          (const_int 0)))])
12292    (parallel [(set (match_dup 0)
12293                    (plus:P (match_dup 3)
12294                            (reg:P CA_REGNO)))
12295               (clobber (reg:P CA_REGNO))])]
12297   operands[4] = rs6000_emit_eqne (<MODE>mode,
12298                                   operands[1], operands[2], operands[4]);
12300   if (GET_CODE (operands[5]) == SCRATCH)
12301     operands[5] = gen_reg_rtx (<MODE>mode);
12303   [(set (attr "length")
12304         (if_then_else (match_test "operands[2] == const0_rtx")
12305                       (const_string "8")
12306                       (const_string "12")))])
12308 (define_insn_and_split "*minus_eq_<mode>"
12309   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12310         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12311                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12312                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12313    (clobber (match_scratch:P 4 "=r"))
12314    (clobber (match_scratch:P 5 "=r"))
12315    (clobber (reg:P CA_REGNO))]
12316   ""
12317   "#"
12318   ""
12319   [(parallel [(set (match_dup 5)
12320                    (plus:P (match_dup 4)
12321                            (const_int -1)))
12322               (set (reg:P CA_REGNO)
12323                    (ne:P (match_dup 4)
12324                          (const_int 0)))])
12325    (parallel [(set (match_dup 0)
12326                    (plus:P (plus:P (match_dup 3)
12327                                    (reg:P CA_REGNO))
12328                            (const_int -1)))
12329               (clobber (reg:P CA_REGNO))])]
12331   operands[4] = rs6000_emit_eqne (<MODE>mode,
12332                                   operands[1], operands[2], operands[4]);
12334   if (GET_CODE (operands[5]) == SCRATCH)
12335     operands[5] = gen_reg_rtx (<MODE>mode);
12337   [(set (attr "length")
12338         (if_then_else (match_test "operands[2] == const0_rtx")
12339                       (const_string "8")
12340                       (const_string "12")))])
12342 (define_insn_and_split "*minus_ne_<mode>"
12343   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12344         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12345                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12346                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12347    (clobber (match_scratch:P 4 "=r"))
12348    (clobber (match_scratch:P 5 "=r"))
12349    (clobber (reg:P CA_REGNO))]
12350   ""
12351   "#"
12352   ""
12353   [(parallel [(set (match_dup 5)
12354                    (neg:P (match_dup 4)))
12355               (set (reg:P CA_REGNO)
12356                    (eq:P (match_dup 4)
12357                          (const_int 0)))])
12358    (parallel [(set (match_dup 0)
12359                    (plus:P (plus:P (match_dup 3)
12360                                    (reg:P CA_REGNO))
12361                            (const_int -1)))
12362               (clobber (reg:P CA_REGNO))])]
12364   operands[4] = rs6000_emit_eqne (<MODE>mode,
12365                                   operands[1], operands[2], operands[4]);
12367   if (GET_CODE (operands[5]) == SCRATCH)
12368     operands[5] = gen_reg_rtx (<MODE>mode);
12370   [(set (attr "length")
12371         (if_then_else (match_test "operands[2] == const0_rtx")
12372                       (const_string "8")
12373                       (const_string "12")))])
12375 (define_insn_and_split "*eqsi3_ext<mode>"
12376   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12377         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12378                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12379    (clobber (match_scratch:SI 3 "=r"))
12380    (clobber (match_scratch:SI 4 "=r"))]
12381   ""
12382   "#"
12383   ""
12384   [(set (match_dup 4)
12385         (clz:SI (match_dup 3)))
12386    (set (match_dup 0)
12387         (zero_extend:EXTSI
12388           (lshiftrt:SI (match_dup 4)
12389                        (const_int 5))))]
12391   operands[3] = rs6000_emit_eqne (SImode,
12392                                   operands[1], operands[2], operands[3]);
12394   if (GET_CODE (operands[4]) == SCRATCH)
12395     operands[4] = gen_reg_rtx (SImode);
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 "*nesi3_ext<mode>"
12403   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12404         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12405                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12406    (clobber (match_scratch:SI 3 "=r"))
12407    (clobber (match_scratch:SI 4 "=r"))
12408    (clobber (match_scratch:EXTSI 5 "=r"))]
12409   ""
12410   "#"
12411   ""
12412   [(set (match_dup 4)
12413         (clz:SI (match_dup 3)))
12414    (set (match_dup 5)
12415         (zero_extend:EXTSI
12416           (lshiftrt:SI (match_dup 4)
12417                        (const_int 5))))
12418    (set (match_dup 0)
12419         (xor:EXTSI (match_dup 5)
12420                    (const_int 1)))]
12422   operands[3] = rs6000_emit_eqne (SImode,
12423                                   operands[1], operands[2], operands[3]);
12425   if (GET_CODE (operands[4]) == SCRATCH)
12426     operands[4] = gen_reg_rtx (SImode);
12427   if (GET_CODE (operands[5]) == SCRATCH)
12428     operands[5] = gen_reg_rtx (<MODE>mode);
12430   [(set (attr "length")
12431         (if_then_else (match_test "operands[2] == const0_rtx")
12432                       (const_string "12")
12433                       (const_string "16")))])
12435 ;; Define both directions of branch and return.  If we need a reload
12436 ;; register, we'd rather use CR0 since it is much easier to copy a
12437 ;; register CC value to there.
12439 (define_insn ""
12440   [(set (pc)
12441         (if_then_else (match_operator 1 "branch_comparison_operator"
12442                                       [(match_operand 2
12443                                                       "cc_reg_operand" "y")
12444                                        (const_int 0)])
12445                       (label_ref (match_operand 0 "" ""))
12446                       (pc)))]
12447   ""
12448   "*
12450   return output_cbranch (operands[1], \"%l0\", 0, insn);
12452   [(set_attr "type" "branch")])
12454 (define_insn ""
12455   [(set (pc)
12456         (if_then_else (match_operator 0 "branch_comparison_operator"
12457                                       [(match_operand 1
12458                                                       "cc_reg_operand" "y")
12459                                        (const_int 0)])
12460                       (any_return)
12461                       (pc)))]
12462   "<return_pred>"
12463   "*
12465   return output_cbranch (operands[0], NULL, 0, insn);
12467   [(set_attr "type" "jmpreg")
12468    (set_attr "length" "4")])
12470 (define_insn ""
12471   [(set (pc)
12472         (if_then_else (match_operator 1 "branch_comparison_operator"
12473                                       [(match_operand 2
12474                                                       "cc_reg_operand" "y")
12475                                        (const_int 0)])
12476                       (pc)
12477                       (label_ref (match_operand 0 "" ""))))]
12478   ""
12479   "*
12481   return output_cbranch (operands[1], \"%l0\", 1, insn);
12483   [(set_attr "type" "branch")])
12485 (define_insn ""
12486   [(set (pc)
12487         (if_then_else (match_operator 0 "branch_comparison_operator"
12488                                       [(match_operand 1
12489                                                       "cc_reg_operand" "y")
12490                                        (const_int 0)])
12491                       (pc)
12492                       (any_return)))]
12493   "<return_pred>"
12494   "*
12496   return output_cbranch (operands[0], NULL, 1, insn);
12498   [(set_attr "type" "jmpreg")
12499    (set_attr "length" "4")])
12501 ;; Logic on condition register values.
12503 ; This pattern matches things like
12504 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12505 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12506 ;                                  (const_int 1)))
12507 ; which are generated by the branch logic.
12508 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12510 (define_insn "*cceq_ior_compare"
12511   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12512         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12513                         [(match_operator:SI 2
12514                                       "branch_positive_comparison_operator"
12515                                       [(match_operand 3
12516                                                       "cc_reg_operand" "y,y")
12517                                        (const_int 0)])
12518                          (match_operator:SI 4
12519                                       "branch_positive_comparison_operator"
12520                                       [(match_operand 5
12521                                                       "cc_reg_operand" "0,y")
12522                                        (const_int 0)])])
12523                       (const_int 1)))]
12524   ""
12525   "cr%q1 %E0,%j2,%j4"
12526   [(set_attr "type" "cr_logical,delayed_cr")])
12528 ; Why is the constant -1 here, but 1 in the previous pattern?
12529 ; Because ~1 has all but the low bit set.
12530 (define_insn ""
12531   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12532         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12533                         [(not:SI (match_operator:SI 2
12534                                       "branch_positive_comparison_operator"
12535                                       [(match_operand 3
12536                                                       "cc_reg_operand" "y,y")
12537                                        (const_int 0)]))
12538                          (match_operator:SI 4
12539                                 "branch_positive_comparison_operator"
12540                                 [(match_operand 5
12541                                                 "cc_reg_operand" "0,y")
12542                                  (const_int 0)])])
12543                       (const_int -1)))]
12544   ""
12545   "cr%q1 %E0,%j2,%j4"
12546   [(set_attr "type" "cr_logical,delayed_cr")])
12548 (define_insn "*cceq_rev_compare"
12549   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12550         (compare:CCEQ (match_operator:SI 1
12551                                       "branch_positive_comparison_operator"
12552                                       [(match_operand 2
12553                                                       "cc_reg_operand" "0,y")
12554                                        (const_int 0)])
12555                       (const_int 0)))]
12556   ""
12557   "crnot %E0,%j1"
12558   [(set_attr "type" "cr_logical,delayed_cr")])
12560 ;; If we are comparing the result of two comparisons, this can be done
12561 ;; using creqv or crxor.
12563 (define_insn_and_split ""
12564   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12565         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12566                               [(match_operand 2 "cc_reg_operand" "y")
12567                                (const_int 0)])
12568                       (match_operator 3 "branch_comparison_operator"
12569                               [(match_operand 4 "cc_reg_operand" "y")
12570                                (const_int 0)])))]
12571   ""
12572   "#"
12573   ""
12574   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12575                                     (match_dup 5)))]
12576   "
12578   int positive_1, positive_2;
12580   positive_1 = branch_positive_comparison_operator (operands[1],
12581                                                     GET_MODE (operands[1]));
12582   positive_2 = branch_positive_comparison_operator (operands[3],
12583                                                     GET_MODE (operands[3]));
12585   if (! positive_1)
12586     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12587                                                             GET_CODE (operands[1])),
12588                                   SImode,
12589                                   operands[2], const0_rtx);
12590   else if (GET_MODE (operands[1]) != SImode)
12591     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12592                                   operands[2], const0_rtx);
12594   if (! positive_2)
12595     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12596                                                             GET_CODE (operands[3])),
12597                                   SImode,
12598                                   operands[4], const0_rtx);
12599   else if (GET_MODE (operands[3]) != SImode)
12600     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12601                                   operands[4], const0_rtx);
12603   if (positive_1 == positive_2)
12604     {
12605       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12606       operands[5] = constm1_rtx;
12607     }
12608   else
12609     {
12610       operands[5] = const1_rtx;
12611     }
12614 ;; Unconditional branch and return.
12616 (define_insn "jump"
12617   [(set (pc)
12618         (label_ref (match_operand 0 "" "")))]
12619   ""
12620   "b %l0"
12621   [(set_attr "type" "branch")])
12623 (define_insn "<return_str>return"
12624   [(any_return)]
12625   "<return_pred>"
12626   "blr"
12627   [(set_attr "type" "jmpreg")])
12629 (define_expand "indirect_jump"
12630   [(set (pc) (match_operand 0 "register_operand" ""))])
12632 (define_insn "*indirect_jump<mode>"
12633   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12634   ""
12635   "@
12636    bctr
12637    blr"
12638   [(set_attr "type" "jmpreg")])
12640 ;; Table jump for switch statements:
12641 (define_expand "tablejump"
12642   [(use (match_operand 0 "" ""))
12643    (use (label_ref (match_operand 1 "" "")))]
12644   ""
12645   "
12647   if (TARGET_32BIT)
12648     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12649   else
12650     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12651   DONE;
12654 (define_expand "tablejumpsi"
12655   [(set (match_dup 3)
12656         (plus:SI (match_operand:SI 0 "" "")
12657                  (match_dup 2)))
12658    (parallel [(set (pc) (match_dup 3))
12659               (use (label_ref (match_operand 1 "" "")))])]
12660   "TARGET_32BIT"
12661   "
12662 { operands[0] = force_reg (SImode, operands[0]);
12663   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12664   operands[3] = gen_reg_rtx (SImode);
12667 (define_expand "tablejumpdi"
12668   [(set (match_dup 4)
12669         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12670    (set (match_dup 3)
12671         (plus:DI (match_dup 4)
12672                  (match_dup 2)))
12673    (parallel [(set (pc) (match_dup 3))
12674               (use (label_ref (match_operand 1 "" "")))])]
12675   "TARGET_64BIT"
12676   "
12677 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12678   operands[3] = gen_reg_rtx (DImode);
12679   operands[4] = gen_reg_rtx (DImode);
12682 (define_insn "*tablejump<mode>_internal1"
12683   [(set (pc)
12684         (match_operand:P 0 "register_operand" "c,*l"))
12685    (use (label_ref (match_operand 1 "" "")))]
12686   ""
12687   "@
12688    bctr
12689    blr"
12690   [(set_attr "type" "jmpreg")])
12692 (define_insn "nop"
12693   [(unspec [(const_int 0)] UNSPEC_NOP)]
12694   ""
12695   "nop")
12697 (define_insn "group_ending_nop"
12698   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12699   ""
12700   "*
12702   if (rs6000_cpu_attr == CPU_POWER6)
12703     return \"ori 1,1,0\";
12704   return \"ori 2,2,0\";
12707 ;; Define the subtract-one-and-jump insns, starting with the template
12708 ;; so loop.c knows what to generate.
12710 (define_expand "doloop_end"
12711   [(use (match_operand 0 "" ""))        ; loop pseudo
12712    (use (match_operand 1 "" ""))]       ; label
12713   ""
12714   "
12716   if (TARGET_64BIT)
12717     {
12718       if (GET_MODE (operands[0]) != DImode)
12719         FAIL;
12720       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12721     }
12722   else
12723     {
12724       if (GET_MODE (operands[0]) != SImode)
12725         FAIL;
12726       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12727     }
12728   DONE;
12731 (define_expand "ctr<mode>"
12732   [(parallel [(set (pc)
12733                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12734                                      (const_int 1))
12735                                  (label_ref (match_operand 1 "" ""))
12736                                  (pc)))
12737               (set (match_dup 0)
12738                    (plus:P (match_dup 0)
12739                             (const_int -1)))
12740               (unspec [(const_int 0)] UNSPEC_DOLOOP)
12741               (clobber (match_scratch:CC 2 ""))
12742               (clobber (match_scratch:P 3 ""))])]
12743   ""
12744   "")
12746 ;; We need to be able to do this for any operand, including MEM, or we
12747 ;; will cause reload to blow up since we don't allow output reloads on
12748 ;; JUMP_INSNs.
12749 ;; For the length attribute to be calculated correctly, the
12750 ;; label MUST be operand 0.
12751 ;; The UNSPEC is present to prevent combine creating this pattern.
12753 (define_insn "*ctr<mode>_internal1"
12754   [(set (pc)
12755         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12756                           (const_int 1))
12757                       (label_ref (match_operand 0 "" ""))
12758                       (pc)))
12759    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12760         (plus:P (match_dup 1)
12761                  (const_int -1)))
12762    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12763    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12764    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12765   ""
12766   "*
12768   if (which_alternative != 0)
12769     return \"#\";
12770   else if (get_attr_length (insn) == 4)
12771     return \"bdnz %l0\";
12772   else
12773     return \"bdz $+8\;b %l0\";
12775   [(set_attr "type" "branch")
12776    (set_attr "length" "*,16,20,20")])
12778 (define_insn "*ctr<mode>_internal2"
12779   [(set (pc)
12780         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12781                           (const_int 1))
12782                       (pc)
12783                       (label_ref (match_operand 0 "" ""))))
12784    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12785         (plus:P (match_dup 1)
12786                  (const_int -1)))
12787    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12788    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12789    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12790   ""
12791   "*
12793   if (which_alternative != 0)
12794     return \"#\";
12795   else if (get_attr_length (insn) == 4)
12796     return \"bdz %l0\";
12797   else
12798     return \"bdnz $+8\;b %l0\";
12800   [(set_attr "type" "branch")
12801    (set_attr "length" "*,16,20,20")])
12803 ;; Similar but use EQ
12805 (define_insn "*ctr<mode>_internal5"
12806   [(set (pc)
12807         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12808                           (const_int 1))
12809                       (label_ref (match_operand 0 "" ""))
12810                       (pc)))
12811    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12812         (plus:P (match_dup 1)
12813                  (const_int -1)))
12814    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12815    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12816    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12817   ""
12818   "*
12820   if (which_alternative != 0)
12821     return \"#\";
12822   else if (get_attr_length (insn) == 4)
12823     return \"bdz %l0\";
12824   else
12825     return \"bdnz $+8\;b %l0\";
12827   [(set_attr "type" "branch")
12828    (set_attr "length" "*,16,20,20")])
12830 (define_insn "*ctr<mode>_internal6"
12831   [(set (pc)
12832         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12833                           (const_int 1))
12834                       (pc)
12835                       (label_ref (match_operand 0 "" ""))))
12836    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12837         (plus:P (match_dup 1)
12838                  (const_int -1)))
12839    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12840    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12841    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12842   ""
12843   "*
12845   if (which_alternative != 0)
12846     return \"#\";
12847   else if (get_attr_length (insn) == 4)
12848     return \"bdnz %l0\";
12849   else
12850     return \"bdz $+8\;b %l0\";
12852   [(set_attr "type" "branch")
12853    (set_attr "length" "*,16,20,20")])
12855 ;; Now the splitters if we could not allocate the CTR register
12857 (define_split
12858   [(set (pc)
12859         (if_then_else (match_operator 2 "comparison_operator"
12860                                       [(match_operand:P 1 "gpc_reg_operand" "")
12861                                        (const_int 1)])
12862                       (match_operand 5 "" "")
12863                       (match_operand 6 "" "")))
12864    (set (match_operand:P 0 "int_reg_operand" "")
12865         (plus:P (match_dup 1) (const_int -1)))
12866    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12867    (clobber (match_scratch:CC 3 ""))
12868    (clobber (match_scratch:P 4 ""))]
12869   "reload_completed"
12870   [(set (match_dup 3)
12871         (compare:CC (match_dup 1)
12872                     (const_int 1)))
12873    (set (match_dup 0)
12874         (plus:P (match_dup 1)
12875                 (const_int -1)))
12876    (set (pc) (if_then_else (match_dup 7)
12877                            (match_dup 5)
12878                            (match_dup 6)))]
12879   "
12880 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12881                                 operands[3], const0_rtx); }")
12883 (define_split
12884   [(set (pc)
12885         (if_then_else (match_operator 2 "comparison_operator"
12886                                       [(match_operand:P 1 "gpc_reg_operand" "")
12887                                        (const_int 1)])
12888                       (match_operand 5 "" "")
12889                       (match_operand 6 "" "")))
12890    (set (match_operand:P 0 "nonimmediate_operand" "")
12891         (plus:P (match_dup 1) (const_int -1)))
12892    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12893    (clobber (match_scratch:CC 3 ""))
12894    (clobber (match_scratch:P 4 ""))]
12895   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12896   [(set (match_dup 3)
12897         (compare:CC (match_dup 1)
12898                     (const_int 1)))
12899    (set (match_dup 4)
12900         (plus:P (match_dup 1)
12901                 (const_int -1)))
12902    (set (match_dup 0)
12903         (match_dup 4))
12904    (set (pc) (if_then_else (match_dup 7)
12905                            (match_dup 5)
12906                            (match_dup 6)))]
12907   "
12908 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12909                                 operands[3], const0_rtx); }")
12911 (define_insn "trap"
12912   [(trap_if (const_int 1) (const_int 0))]
12913   ""
12914   "trap"
12915   [(set_attr "type" "trap")])
12917 (define_expand "ctrap<mode>4"
12918   [(trap_if (match_operator 0 "ordered_comparison_operator"
12919                             [(match_operand:GPR 1 "register_operand")
12920                              (match_operand:GPR 2 "reg_or_short_operand")])
12921             (match_operand 3 "zero_constant" ""))]
12922   ""
12923   "")
12925 (define_insn ""
12926   [(trap_if (match_operator 0 "ordered_comparison_operator"
12927                             [(match_operand:GPR 1 "register_operand" "r")
12928                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12929             (const_int 0))]
12930   ""
12931   "t<wd>%V0%I2 %1,%2"
12932   [(set_attr "type" "trap")])
12934 ;; Insns related to generating the function prologue and epilogue.
12936 (define_expand "prologue"
12937   [(use (const_int 0))]
12938   ""
12940   rs6000_emit_prologue ();
12941   if (!TARGET_SCHED_PROLOG)
12942     emit_insn (gen_blockage ());
12943   DONE;
12946 (define_insn "*movesi_from_cr_one"
12947   [(match_parallel 0 "mfcr_operation"
12948                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12949                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12950                                      (match_operand 3 "immediate_operand" "n")]
12951                           UNSPEC_MOVESI_FROM_CR))])]
12952   "TARGET_MFCRF"
12953   "*
12955   int mask = 0;
12956   int i;
12957   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12958   {
12959     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12960     operands[4] = GEN_INT (mask);
12961     output_asm_insn (\"mfcr %1,%4\", operands);
12962   }
12963   return \"\";
12965   [(set_attr "type" "mfcrf")])
12967 (define_insn "movesi_from_cr"
12968   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12969         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12970                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12971                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12972                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12973                    UNSPEC_MOVESI_FROM_CR))]
12974   ""
12975   "mfcr %0"
12976   [(set_attr "type" "mfcr")])
12978 (define_insn "*crsave"
12979   [(match_parallel 0 "crsave_operation"
12980                    [(set (match_operand:SI 1 "memory_operand" "=m")
12981                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12982   ""
12983   "stw %2,%1"
12984   [(set_attr "type" "store")])
12986 (define_insn "*stmw"
12987   [(match_parallel 0 "stmw_operation"
12988                    [(set (match_operand:SI 1 "memory_operand" "=m")
12989                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12990   "TARGET_MULTIPLE"
12991   "stmw %2,%1"
12992   [(set_attr "type" "store")
12993    (set_attr "update" "yes")
12994    (set_attr "indexed" "yes")])
12996 ; The following comment applies to:
12997 ;     save_gpregs_*
12998 ;     save_fpregs_*
12999 ;     restore_gpregs*
13000 ;     return_and_restore_gpregs*
13001 ;     return_and_restore_fpregs*
13002 ;     return_and_restore_fpregs_aix*
13004 ; The out-of-line save / restore functions expects one input argument.
13005 ; Since those are not standard call_insn's, we must avoid using
13006 ; MATCH_OPERAND for that argument. That way the register rename
13007 ; optimization will not try to rename this register.
13008 ; Each pattern is repeated for each possible register number used in 
13009 ; various ABIs (r11, r1, and for some functions r12)
13011 (define_insn "*save_gpregs_<mode>_r11"
13012   [(match_parallel 0 "any_parallel_operand"
13013                    [(clobber (reg:P LR_REGNO))
13014                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13015                     (use (reg:P 11))
13016                     (set (match_operand:P 2 "memory_operand" "=m")
13017                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13018   ""
13019   "bl %1"
13020   [(set_attr "type" "branch")
13021    (set_attr "length" "4")])
13023 (define_insn "*save_gpregs_<mode>_r12"
13024   [(match_parallel 0 "any_parallel_operand"
13025                    [(clobber (reg:P LR_REGNO))
13026                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13027                     (use (reg:P 12))
13028                     (set (match_operand:P 2 "memory_operand" "=m")
13029                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13030   ""
13031   "bl %1"
13032   [(set_attr "type" "branch")
13033    (set_attr "length" "4")])
13035 (define_insn "*save_gpregs_<mode>_r1"
13036   [(match_parallel 0 "any_parallel_operand"
13037                    [(clobber (reg:P LR_REGNO))
13038                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13039                     (use (reg:P 1))
13040                     (set (match_operand:P 2 "memory_operand" "=m")
13041                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13042   ""
13043   "bl %1"
13044   [(set_attr "type" "branch")
13045    (set_attr "length" "4")])
13047 (define_insn "*save_fpregs_<mode>_r11"
13048   [(match_parallel 0 "any_parallel_operand"
13049                    [(clobber (reg:P LR_REGNO))
13050                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13051                     (use (reg:P 11))
13052                     (set (match_operand:DF 2 "memory_operand" "=m")
13053                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13054   ""
13055   "bl %1"
13056   [(set_attr "type" "branch")
13057    (set_attr "length" "4")])
13059 (define_insn "*save_fpregs_<mode>_r12"
13060   [(match_parallel 0 "any_parallel_operand"
13061                    [(clobber (reg:P LR_REGNO))
13062                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13063                     (use (reg:P 12))
13064                     (set (match_operand:DF 2 "memory_operand" "=m")
13065                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13066   ""
13067   "bl %1"
13068   [(set_attr "type" "branch")
13069    (set_attr "length" "4")])
13071 (define_insn "*save_fpregs_<mode>_r1"
13072   [(match_parallel 0 "any_parallel_operand"
13073                    [(clobber (reg:P LR_REGNO))
13074                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13075                     (use (reg:P 1))
13076                     (set (match_operand:DF 2 "memory_operand" "=m")
13077                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13078   ""
13079   "bl %1"
13080   [(set_attr "type" "branch")
13081    (set_attr "length" "4")])
13083 ; This is to explain that changes to the stack pointer should
13084 ; not be moved over loads from or stores to stack memory.
13085 (define_insn "stack_tie"
13086   [(match_parallel 0 "tie_operand"
13087                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13088   ""
13089   ""
13090   [(set_attr "length" "0")])
13092 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13093 ; stay behind all restores from the stack, it cannot be reordered to before
13094 ; one.  See PR77687.  This insn is an add or mr, and a stack_tie on the
13095 ; operands of that.
13096 (define_insn "stack_restore_tie"
13097   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13098         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13099                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13100    (set (mem:BLK (match_dup 0)) (const_int 0))
13101    (set (mem:BLK (match_dup 1)) (const_int 0))]
13102   "TARGET_32BIT"
13103   "@
13104    mr %0,%1
13105    add%I2 %0,%1,%2"
13106   [(set_attr "type" "*,add")])
13108 (define_expand "epilogue"
13109   [(use (const_int 0))]
13110   ""
13112   if (!TARGET_SCHED_PROLOG)
13113     emit_insn (gen_blockage ());
13114   rs6000_emit_epilogue (FALSE);
13115   DONE;
13118 ; On some processors, doing the mtcrf one CC register at a time is
13119 ; faster (like on the 604e).  On others, doing them all at once is
13120 ; faster; for instance, on the 601 and 750.
13122 (define_expand "movsi_to_cr_one"
13123   [(set (match_operand:CC 0 "cc_reg_operand" "")
13124         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13125                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13126   ""
13127   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13129 (define_insn "*movsi_to_cr"
13130   [(match_parallel 0 "mtcrf_operation"
13131                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13132                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13133                                      (match_operand 3 "immediate_operand" "n")]
13134                                     UNSPEC_MOVESI_TO_CR))])]
13135  ""
13136  "*
13138   int mask = 0;
13139   int i;
13140   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13141     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13142   operands[4] = GEN_INT (mask);
13143   return \"mtcrf %4,%2\";
13145   [(set_attr "type" "mtcr")])
13147 (define_insn "*mtcrfsi"
13148   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13149         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13150                     (match_operand 2 "immediate_operand" "n")]
13151                    UNSPEC_MOVESI_TO_CR))]
13152   "GET_CODE (operands[0]) == REG
13153    && CR_REGNO_P (REGNO (operands[0]))
13154    && GET_CODE (operands[2]) == CONST_INT
13155    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13156   "mtcrf %R0,%1"
13157   [(set_attr "type" "mtcr")])
13159 ; The load-multiple instructions have similar properties.
13160 ; Note that "load_multiple" is a name known to the machine-independent
13161 ; code that actually corresponds to the PowerPC load-string.
13163 (define_insn "*lmw"
13164   [(match_parallel 0 "lmw_operation"
13165                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13166                          (match_operand:SI 2 "memory_operand" "m"))])]
13167   "TARGET_MULTIPLE"
13168   "lmw %1,%2"
13169   [(set_attr "type" "load")
13170    (set_attr "update" "yes")
13171    (set_attr "indexed" "yes")
13172    (set_attr "cell_micro" "always")])
13174 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13175 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13177 ; The following comment applies to:
13178 ;     save_gpregs_*
13179 ;     save_fpregs_*
13180 ;     restore_gpregs*
13181 ;     return_and_restore_gpregs*
13182 ;     return_and_restore_fpregs*
13183 ;     return_and_restore_fpregs_aix*
13185 ; The out-of-line save / restore functions expects one input argument.
13186 ; Since those are not standard call_insn's, we must avoid using
13187 ; MATCH_OPERAND for that argument. That way the register rename
13188 ; optimization will not try to rename this register.
13189 ; Each pattern is repeated for each possible register number used in 
13190 ; various ABIs (r11, r1, and for some functions r12)
13192 (define_insn "*restore_gpregs_<mode>_r11"
13193  [(match_parallel 0 "any_parallel_operand"
13194                   [(clobber (reg:P LR_REGNO))
13195                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13196                    (use (reg:P 11))
13197                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13198                         (match_operand:P 3 "memory_operand" "m"))])]
13199  ""
13200  "bl %1"
13201  [(set_attr "type" "branch")
13202   (set_attr "length" "4")])
13204 (define_insn "*restore_gpregs_<mode>_r12"
13205  [(match_parallel 0 "any_parallel_operand"
13206                   [(clobber (reg:P LR_REGNO))
13207                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13208                    (use (reg:P 12))
13209                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13210                         (match_operand:P 3 "memory_operand" "m"))])]
13211  ""
13212  "bl %1"
13213  [(set_attr "type" "branch")
13214   (set_attr "length" "4")])
13216 (define_insn "*restore_gpregs_<mode>_r1"
13217  [(match_parallel 0 "any_parallel_operand"
13218                   [(clobber (reg:P LR_REGNO))
13219                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13220                    (use (reg:P 1))
13221                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13222                         (match_operand:P 3 "memory_operand" "m"))])]
13223  ""
13224  "bl %1"
13225  [(set_attr "type" "branch")
13226   (set_attr "length" "4")])
13228 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13229  [(match_parallel 0 "any_parallel_operand"
13230                   [(return)
13231                    (clobber (reg:P LR_REGNO))
13232                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13233                    (use (reg:P 11))
13234                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13235                         (match_operand:P 3 "memory_operand" "m"))])]
13236  ""
13237  "b %1"
13238  [(set_attr "type" "branch")
13239   (set_attr "length" "4")])
13241 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13242  [(match_parallel 0 "any_parallel_operand"
13243                   [(return)
13244                    (clobber (reg:P LR_REGNO))
13245                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13246                    (use (reg:P 12))
13247                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13248                         (match_operand:P 3 "memory_operand" "m"))])]
13249  ""
13250  "b %1"
13251  [(set_attr "type" "branch")
13252   (set_attr "length" "4")])
13254 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13255  [(match_parallel 0 "any_parallel_operand"
13256                   [(return)
13257                    (clobber (reg:P LR_REGNO))
13258                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13259                    (use (reg:P 1))
13260                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13261                         (match_operand:P 3 "memory_operand" "m"))])]
13262  ""
13263  "b %1"
13264  [(set_attr "type" "branch")
13265   (set_attr "length" "4")])
13267 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13268  [(match_parallel 0 "any_parallel_operand"
13269                   [(return)
13270                    (clobber (reg:P LR_REGNO))
13271                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13272                    (use (reg:P 11))
13273                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13274                         (match_operand:DF 3 "memory_operand" "m"))])]
13275  ""
13276  "b %1"
13277  [(set_attr "type" "branch")
13278   (set_attr "length" "4")])
13280 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13281  [(match_parallel 0 "any_parallel_operand"
13282                   [(return)
13283                    (clobber (reg:P LR_REGNO))
13284                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13285                    (use (reg:P 12))
13286                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13287                         (match_operand:DF 3 "memory_operand" "m"))])]
13288  ""
13289  "b %1"
13290  [(set_attr "type" "branch")
13291   (set_attr "length" "4")])
13293 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13294  [(match_parallel 0 "any_parallel_operand"
13295                   [(return)
13296                    (clobber (reg:P LR_REGNO))
13297                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13298                    (use (reg:P 1))
13299                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13300                         (match_operand:DF 3 "memory_operand" "m"))])]
13301  ""
13302  "b %1"
13303  [(set_attr "type" "branch")
13304   (set_attr "length" "4")])
13306 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13307  [(match_parallel 0 "any_parallel_operand"
13308                   [(return)
13309                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13310                    (use (reg:P 11))
13311                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13312                         (match_operand:DF 3 "memory_operand" "m"))])]
13313  ""
13314  "b %1"
13315  [(set_attr "type" "branch")
13316   (set_attr "length" "4")])
13318 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13319  [(match_parallel 0 "any_parallel_operand"
13320                   [(return)
13321                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13322                    (use (reg:P 1))
13323                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13324                         (match_operand:DF 3 "memory_operand" "m"))])]
13325  ""
13326  "b %1"
13327  [(set_attr "type" "branch")
13328   (set_attr "length" "4")])
13330 ; This is used in compiling the unwind routines.
13331 (define_expand "eh_return"
13332   [(use (match_operand 0 "general_operand" ""))]
13333   ""
13334   "
13336   if (TARGET_32BIT)
13337     emit_insn (gen_eh_set_lr_si (operands[0]));
13338   else
13339     emit_insn (gen_eh_set_lr_di (operands[0]));
13340   DONE;
13343 ; We can't expand this before we know where the link register is stored.
13344 (define_insn "eh_set_lr_<mode>"
13345   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13346                     UNSPECV_EH_RR)
13347    (clobber (match_scratch:P 1 "=&b"))]
13348   ""
13349   "#")
13351 (define_split
13352   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13353    (clobber (match_scratch 1 ""))]
13354   "reload_completed"
13355   [(const_int 0)]
13356   "
13358   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13359   DONE;
13362 (define_insn "prefetch"
13363   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13364              (match_operand:SI 1 "const_int_operand" "n")
13365              (match_operand:SI 2 "const_int_operand" "n"))]
13366   ""
13367   "*
13369   if (GET_CODE (operands[0]) == REG)
13370     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13371   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13373   [(set_attr "type" "load")])
13375 ;; Handle -fsplit-stack.
13377 (define_expand "split_stack_prologue"
13378   [(const_int 0)]
13379   ""
13381   rs6000_expand_split_stack_prologue ();
13382   DONE;
13385 (define_expand "load_split_stack_limit"
13386   [(set (match_operand 0)
13387         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13388   ""
13390   emit_insn (gen_rtx_SET (operands[0],
13391                           gen_rtx_UNSPEC (Pmode,
13392                                           gen_rtvec (1, const0_rtx),
13393                                           UNSPEC_STACK_CHECK)));
13394   DONE;
13397 (define_insn "load_split_stack_limit_di"
13398   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13399         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13400   "TARGET_64BIT"
13401   "ld %0,-0x7040(13)"
13402   [(set_attr "type" "load")
13403    (set_attr "update" "no")
13404    (set_attr "indexed" "no")])
13406 (define_insn "load_split_stack_limit_si"
13407   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13408         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13409   "!TARGET_64BIT"
13410   "lwz %0,-0x7020(2)"
13411   [(set_attr "type" "load")
13412    (set_attr "update" "no")
13413    (set_attr "indexed" "no")])
13415 ;; A return instruction which the middle-end doesn't see.
13416 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13417 ;; after the call to __morestack.
13418 (define_insn "split_stack_return"
13419   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13420   ""
13421   "blr"
13422   [(set_attr "type" "jmpreg")])
13424 ;; If there are operand 0 bytes available on the stack, jump to
13425 ;; operand 1.
13426 (define_expand "split_stack_space_check"
13427   [(set (match_dup 2)
13428         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13429    (set (match_dup 3)
13430         (minus (reg STACK_POINTER_REGNUM)
13431                (match_operand 0)))
13432    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13433    (set (pc) (if_then_else
13434               (geu (match_dup 4) (const_int 0))
13435               (label_ref (match_operand 1))
13436               (pc)))]
13437   ""
13439   rs6000_split_stack_space_check (operands[0], operands[1]);
13440   DONE;
13443 (define_insn "bpermd_<mode>"
13444   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13445         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13446                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13447   "TARGET_POPCNTD"
13448   "bpermd %0,%1,%2"
13449   [(set_attr "type" "popcnt")])
13452 ;; Builtin fma support.  Handle 
13453 ;; Note that the conditions for expansion are in the FMA_F iterator.
13455 (define_expand "fma<mode>4"
13456   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13457         (fma:FMA_F
13458           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13459           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13460           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13461   ""
13462   "")
13464 (define_insn "*fma<mode>4_fpr"
13465   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13466         (fma:SFDF
13467           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13468           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13469           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13470   "TARGET_<MODE>_FPR"
13471   "@
13472    fmadd<Ftrad> %0,%1,%2,%3
13473    xsmadda<Fvsx> %x0,%x1,%x2
13474    xsmaddm<Fvsx> %x0,%x1,%x3"
13475   [(set_attr "type" "fp")
13476    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13478 ; Altivec only has fma and nfms.
13479 (define_expand "fms<mode>4"
13480   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13481         (fma:FMA_F
13482           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13483           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13484           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13485   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13486   "")
13488 (define_insn "*fms<mode>4_fpr"
13489   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13490         (fma:SFDF
13491          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13492          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13493          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13494   "TARGET_<MODE>_FPR"
13495   "@
13496    fmsub<Ftrad> %0,%1,%2,%3
13497    xsmsuba<Fvsx> %x0,%x1,%x2
13498    xsmsubm<Fvsx> %x0,%x1,%x3"
13499   [(set_attr "type" "fp")
13500    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13502 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13503 (define_expand "fnma<mode>4"
13504   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13505         (neg:FMA_F
13506           (fma:FMA_F
13507             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13508             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13509             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13510   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13511   "")
13513 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13514 (define_expand "fnms<mode>4"
13515   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13516         (neg:FMA_F
13517           (fma:FMA_F
13518             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13519             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13520             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13521   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13522   "")
13524 ; Not an official optab name, but used from builtins.
13525 (define_expand "nfma<mode>4"
13526   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13527         (neg:FMA_F
13528           (fma:FMA_F
13529             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13530             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13531             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13532   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13533   "")
13535 (define_insn "*nfma<mode>4_fpr"
13536   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13537         (neg:SFDF
13538          (fma:SFDF
13539           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13540           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13541           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13542   "TARGET_<MODE>_FPR"
13543   "@
13544    fnmadd<Ftrad> %0,%1,%2,%3
13545    xsnmadda<Fvsx> %x0,%x1,%x2
13546    xsnmaddm<Fvsx> %x0,%x1,%x3"
13547   [(set_attr "type" "fp")
13548    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13550 ; Not an official optab name, but used from builtins.
13551 (define_expand "nfms<mode>4"
13552   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13553         (neg:FMA_F
13554           (fma:FMA_F
13555             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13556             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13557             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13558   ""
13559   "")
13561 (define_insn "*nfmssf4_fpr"
13562   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13563         (neg:SFDF
13564          (fma:SFDF
13565           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13566           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13567           (neg:SFDF
13568            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13569   "TARGET_<MODE>_FPR"
13570   "@
13571    fnmsub<Ftrad> %0,%1,%2,%3
13572    xsnmsuba<Fvsx> %x0,%x1,%x2
13573    xsnmsubm<Fvsx> %x0,%x1,%x3"
13574   [(set_attr "type" "fp")
13575    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13578 (define_expand "rs6000_get_timebase"
13579   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13580   ""
13582   if (TARGET_POWERPC64)
13583     emit_insn (gen_rs6000_mftb_di (operands[0]));
13584   else
13585     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13586   DONE;
13589 (define_insn "rs6000_get_timebase_ppc32"
13590   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13591         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13592    (clobber (match_scratch:SI 1 "=r"))
13593    (clobber (match_scratch:CC 2 "=y"))]
13594   "!TARGET_POWERPC64"
13596   if (WORDS_BIG_ENDIAN)
13597     if (TARGET_MFCRF)
13598       {
13599         return "mfspr %0,269\;"
13600                "mfspr %L0,268\;"
13601                "mfspr %1,269\;"
13602                "cmpw %2,%0,%1\;"
13603                "bne- %2,$-16";
13604       }
13605     else
13606       {
13607         return "mftbu %0\;"
13608                "mftb %L0\;"
13609                "mftbu %1\;"
13610                "cmpw %2,%0,%1\;"
13611                "bne- %2,$-16";
13612       }
13613   else
13614     if (TARGET_MFCRF)
13615       {
13616         return "mfspr %L0,269\;"
13617                "mfspr %0,268\;"
13618                "mfspr %1,269\;"
13619                "cmpw %2,%L0,%1\;"
13620                "bne- %2,$-16";
13621       }
13622     else
13623       {
13624         return "mftbu %L0\;"
13625                "mftb %0\;"
13626                "mftbu %1\;"
13627                "cmpw %2,%L0,%1\;"
13628                "bne- %2,$-16";
13629       }
13631   [(set_attr "length" "20")])
13633 (define_insn "rs6000_mftb_<mode>"
13634   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13635         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13636   ""
13638   if (TARGET_MFCRF)
13639     return "mfspr %0,268";
13640   else
13641     return "mftb %0";
13645 (define_insn "rs6000_mffs"
13646   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13647         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13648   "TARGET_HARD_FLOAT && TARGET_FPRS"
13649   "mffs %0")
13651 (define_insn "rs6000_mtfsf"
13652   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13653                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13654                     UNSPECV_MTFSF)]
13655   "TARGET_HARD_FLOAT && TARGET_FPRS"
13656   "mtfsf %0,%1")
13659 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13660 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13661 ;; register that is being loaded.  The fused ops must be physically adjacent.
13663 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13664 ;; before register allocation, and is meant to reduce the lifetime for the
13665 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13666 ;; to use the register that is being load.  The peephole2 then gathers any
13667 ;; other fused possibilities that it can find after register allocation.  If
13668 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13670 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13671 ;; before register allocation, so that we can avoid allocating a temporary base
13672 ;; register that won't be used, and that we try to load into base registers,
13673 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13674 ;; (addis followed by load) even on power8.
13676 (define_split
13677   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13678         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13679   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13680   [(parallel [(set (match_dup 0) (match_dup 2))
13681               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13682               (use (match_dup 3))
13683               (clobber (scratch:DI))])]
13685   operands[2] = fusion_wrap_memory_address (operands[1]);
13686   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13689 (define_insn "*toc_fusionload_<mode>"
13690   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13691         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13692    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13693    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13694    (clobber (match_scratch:DI 3 "=X,&b"))]
13695   "TARGET_TOC_FUSION_INT"
13697   if (base_reg_operand (operands[0], <MODE>mode))
13698     return emit_fusion_gpr_load (operands[0], operands[1]);
13700   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13702   [(set_attr "type" "load")
13703    (set_attr "length" "8")])
13705 (define_insn "*toc_fusionload_di"
13706   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13707         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13708    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13709    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13710    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13711   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13712    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13714   if (base_reg_operand (operands[0], DImode))
13715     return emit_fusion_gpr_load (operands[0], operands[1]);
13717   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13719   [(set_attr "type" "load")
13720    (set_attr "length" "8")])
13723 ;; Find cases where the addis that feeds into a load instruction is either used
13724 ;; once or is the same as the target register, and replace it with the fusion
13725 ;; insn
13727 (define_peephole2
13728   [(set (match_operand:P 0 "base_reg_operand" "")
13729         (match_operand:P 1 "fusion_gpr_addis" ""))
13730    (set (match_operand:INT1 2 "base_reg_operand" "")
13731         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13732   "TARGET_P8_FUSION
13733    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13734                          operands[3])"
13735   [(const_int 0)]
13737   expand_fusion_gpr_load (operands);
13738   DONE;
13741 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13742 ;; reload)
13744 (define_insn "fusion_gpr_load_<mode>"
13745   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13746         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13747                      UNSPEC_FUSION_GPR))]
13748   "TARGET_P8_FUSION"
13750   return emit_fusion_gpr_load (operands[0], operands[1]);
13752   [(set_attr "type" "load")
13753    (set_attr "length" "8")])
13756 ;; ISA 3.0 (power9) fusion support
13757 ;; Merge addis with floating load/store to FPRs (or GPRs).
13758 (define_peephole2
13759   [(set (match_operand:P 0 "base_reg_operand" "")
13760         (match_operand:P 1 "fusion_gpr_addis" ""))
13761    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13762         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13763   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13764    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13765   [(const_int 0)]
13767   expand_fusion_p9_load (operands);
13768   DONE;
13771 (define_peephole2
13772   [(set (match_operand:P 0 "base_reg_operand" "")
13773         (match_operand:P 1 "fusion_gpr_addis" ""))
13774    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13775         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13776   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13777    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13778    && !rtx_equal_p (operands[0], operands[3])"
13779   [(const_int 0)]
13781   expand_fusion_p9_store (operands);
13782   DONE;
13785 (define_peephole2
13786   [(set (match_operand:SDI 0 "int_reg_operand" "")
13787         (match_operand:SDI 1 "upper16_cint_operand" ""))
13788    (set (match_dup 0)
13789         (ior:SDI (match_dup 0)
13790                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13791   "TARGET_P9_FUSION"
13792   [(set (match_dup 0)
13793         (unspec:SDI [(match_dup 1)
13794                      (match_dup 2)] UNSPEC_FUSION_P9))])
13796 (define_peephole2
13797   [(set (match_operand:SDI 0 "int_reg_operand" "")
13798         (match_operand:SDI 1 "upper16_cint_operand" ""))
13799    (set (match_operand:SDI 2 "int_reg_operand" "")
13800         (ior:SDI (match_dup 0)
13801                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13802   "TARGET_P9_FUSION
13803    && !rtx_equal_p (operands[0], operands[2])
13804    && peep2_reg_dead_p (2, operands[0])"
13805   [(set (match_dup 2)
13806         (unspec:SDI [(match_dup 1)
13807                      (match_dup 3)] UNSPEC_FUSION_P9))])
13809 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13810 ;; reload).  Because we want to eventually have secondary_reload generate
13811 ;; these, they have to have a single alternative that gives the register
13812 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13813 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13814   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13815         (unspec:GPR_FUSION
13816          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13817          UNSPEC_FUSION_P9))
13818    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13819   "TARGET_P9_FUSION"
13821   /* This insn is a secondary reload insn, which cannot have alternatives.
13822      If we are not loading up register 0, use the power8 fusion instead.  */
13823   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13824     return emit_fusion_gpr_load (operands[0], operands[1]);
13826   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13828   [(set_attr "type" "load")
13829    (set_attr "length" "8")])
13831 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13832   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13833         (unspec:GPR_FUSION
13834          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13835          UNSPEC_FUSION_P9))
13836    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13837   "TARGET_P9_FUSION"
13839   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13841   [(set_attr "type" "store")
13842    (set_attr "length" "8")])
13844 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13845   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13846         (unspec:FPR_FUSION
13847          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13848          UNSPEC_FUSION_P9))
13849    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13850   "TARGET_P9_FUSION"
13852   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13854   [(set_attr "type" "fpload")
13855    (set_attr "length" "8")])
13857 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13858   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13859         (unspec:FPR_FUSION
13860          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13861          UNSPEC_FUSION_P9))
13862    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13863   "TARGET_P9_FUSION"
13865   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13867   [(set_attr "type" "fpstore")
13868    (set_attr "length" "8")])
13870 (define_insn "*fusion_p9_<mode>_constant"
13871   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13872         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13873                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13874                     UNSPEC_FUSION_P9))] 
13875   "TARGET_P9_FUSION"
13877   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13878   return "ori %0,%0,%2";
13880   [(set_attr "type" "two")
13881    (set_attr "length" "8")])
13884 ;; Miscellaneous ISA 2.06 (power7) instructions
13885 (define_insn "addg6s"
13886   [(set (match_operand:SI 0 "register_operand" "=r")
13887         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13888                     (match_operand:SI 2 "register_operand" "r")]
13889                    UNSPEC_ADDG6S))]
13890   "TARGET_POPCNTD"
13891   "addg6s %0,%1,%2"
13892   [(set_attr "type" "integer")
13893    (set_attr "length" "4")])
13895 (define_insn "cdtbcd"
13896   [(set (match_operand:SI 0 "register_operand" "=r")
13897         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13898                    UNSPEC_CDTBCD))]
13899   "TARGET_POPCNTD"
13900   "cdtbcd %0,%1"
13901   [(set_attr "type" "integer")
13902    (set_attr "length" "4")])
13904 (define_insn "cbcdtd"
13905   [(set (match_operand:SI 0 "register_operand" "=r")
13906         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13907                    UNSPEC_CBCDTD))]
13908   "TARGET_POPCNTD"
13909   "cbcdtd %0,%1"
13910   [(set_attr "type" "integer")
13911    (set_attr "length" "4")])
13913 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13914                                         UNSPEC_DIVEO
13915                                         UNSPEC_DIVEU
13916                                         UNSPEC_DIVEUO])
13918 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13919                              (UNSPEC_DIVEO      "eo")
13920                              (UNSPEC_DIVEU      "eu")
13921                              (UNSPEC_DIVEUO     "euo")])
13923 (define_insn "div<div_extend>_<mode>"
13924   [(set (match_operand:GPR 0 "register_operand" "=r")
13925         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13926                      (match_operand:GPR 2 "register_operand" "r")]
13927                     UNSPEC_DIV_EXTEND))]
13928   "TARGET_POPCNTD"
13929   "div<wd><div_extend> %0,%1,%2"
13930   [(set_attr "type" "div")
13931    (set_attr "size" "<bits>")])
13934 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13936 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13937 (define_mode_attr FP128_64 [(TF "DF")
13938                             (IF "DF")
13939                             (TD "DI")
13940                             (KF "DI")])
13942 (define_expand "unpack<mode>"
13943   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13944         (unspec:<FP128_64>
13945          [(match_operand:FMOVE128 1 "register_operand" "")
13946           (match_operand:QI 2 "const_0_to_1_operand" "")]
13947          UNSPEC_UNPACK_128BIT))]
13948   "FLOAT128_2REG_P (<MODE>mode)"
13949   "")
13951 (define_insn_and_split "unpack<mode>_dm"
13952   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13953         (unspec:<FP128_64>
13954          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13955           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13956          UNSPEC_UNPACK_128BIT))]
13957   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13958   "#"
13959   "&& reload_completed"
13960   [(set (match_dup 0) (match_dup 3))]
13962   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13964   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13965     {
13966       emit_note (NOTE_INSN_DELETED);
13967       DONE;
13968     }
13970   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13972   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13973    (set_attr "length" "4")])
13975 (define_insn_and_split "unpack<mode>_nodm"
13976   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13977         (unspec:<FP128_64>
13978          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13979           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13980          UNSPEC_UNPACK_128BIT))]
13981   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13982   "#"
13983   "&& reload_completed"
13984   [(set (match_dup 0) (match_dup 3))]
13986   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13988   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13989     {
13990       emit_note (NOTE_INSN_DELETED);
13991       DONE;
13992     }
13994   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13996   [(set_attr "type" "fp,fpstore")
13997    (set_attr "length" "4")])
13999 (define_insn_and_split "pack<mode>"
14000   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14001         (unspec:FMOVE128
14002          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14003           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14004          UNSPEC_PACK_128BIT))]
14005   "FLOAT128_2REG_P (<MODE>mode)"
14006   "@
14007    fmr %L0,%2
14008    #"
14009   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14010   [(set (match_dup 3) (match_dup 1))
14011    (set (match_dup 4) (match_dup 2))]
14013   unsigned dest_hi = REGNO (operands[0]);
14014   unsigned dest_lo = dest_hi + 1;
14016   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14017   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14019   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14020   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14022   [(set_attr "type" "fpsimple,fp")
14023    (set_attr "length" "4,8")])
14025 (define_insn "unpack<mode>"
14026   [(set (match_operand:DI 0 "register_operand" "=d,d")
14027         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14028                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14029          UNSPEC_UNPACK_128BIT))]
14030   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14032   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14033     return ASM_COMMENT_START " xxpermdi to same register";
14035   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14036   return "xxpermdi %x0,%x1,%x1,%3";
14038   [(set_attr "type" "vecperm")])
14040 (define_insn "pack<mode>"
14041   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14042         (unspec:FMOVE128_VSX
14043          [(match_operand:DI 1 "register_operand" "d")
14044           (match_operand:DI 2 "register_operand" "d")]
14045          UNSPEC_PACK_128BIT))]
14046   "TARGET_VSX"
14047   "xxpermdi %x0,%x1,%x2,0"
14048   [(set_attr "type" "vecperm")])
14052 ;; ISA 2.08 IEEE 128-bit floating point support.
14054 (define_insn "add<mode>3"
14055   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14056         (plus:IEEE128
14057          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14058          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14059   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14060   "xsaddqp %0,%1,%2"
14061   [(set_attr "type" "vecfloat")
14062    (set_attr "size" "128")])
14064 (define_insn "sub<mode>3"
14065   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14066         (minus:IEEE128
14067          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14068          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14069   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14070   "xssubqp %0,%1,%2"
14071   [(set_attr "type" "vecfloat")
14072    (set_attr "size" "128")])
14074 (define_insn "mul<mode>3"
14075   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14076         (mult:IEEE128
14077          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14078          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14079   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14080   "xsmulqp %0,%1,%2"
14081   [(set_attr "type" "vecfloat")
14082    (set_attr "size" "128")])
14084 (define_insn "div<mode>3"
14085   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14086         (div:IEEE128
14087          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14088          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14089   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14090   "xsdivqp %0,%1,%2"
14091   [(set_attr "type" "vecdiv")
14092    (set_attr "size" "128")])
14094 (define_insn "sqrt<mode>2"
14095   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14096         (sqrt:IEEE128
14097          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14098   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14099    "xssqrtqp %0,%1"
14100   [(set_attr "type" "vecdiv")
14101    (set_attr "size" "128")])
14103 (define_expand "copysign<mode>3"
14104   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14105    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14106    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14107   "FLOAT128_IEEE_P (<MODE>mode)"
14109   if (TARGET_FLOAT128_HW)
14110     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14111                                          operands[2]));
14112   else
14113     {
14114       rtx tmp = gen_reg_rtx (<MODE>mode);
14115       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14116                                            operands[2], tmp));
14117     }
14118   DONE;
14121 (define_insn "copysign<mode>3_hard"
14122   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14123         (unspec:IEEE128
14124          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14125           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14126          UNSPEC_COPYSIGN))]
14127   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14128    "xscpsgnqp %0,%2,%1"
14129   [(set_attr "type" "vecmove")
14130    (set_attr "size" "128")])
14132 (define_insn "copysign<mode>3_soft"
14133   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14134         (unspec:IEEE128
14135          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14136           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14137           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14138          UNSPEC_COPYSIGN))]
14139   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14140    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14141   [(set_attr "type" "veccomplex")
14142    (set_attr "length" "8")])
14144 (define_insn "neg<mode>2_hw"
14145   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14146         (neg:IEEE128
14147          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14148   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14149   "xsnegqp %0,%1"
14150   [(set_attr "type" "vecmove")
14151    (set_attr "size" "128")])
14154 (define_insn "abs<mode>2_hw"
14155   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14156         (abs:IEEE128
14157          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14158   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14159   "xsabsqp %0,%1"
14160   [(set_attr "type" "vecmove")
14161    (set_attr "size" "128")])
14164 (define_insn "*nabs<mode>2_hw"
14165   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14166         (neg:IEEE128
14167          (abs:IEEE128
14168           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14169   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14170   "xsnabsqp %0,%1"
14171   [(set_attr "type" "vecmove")
14172    (set_attr "size" "128")])
14174 ;; Initially don't worry about doing fusion
14175 (define_insn "*fma<mode>4_hw"
14176   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14177         (fma:IEEE128
14178          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14179          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14180          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14181   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14182   "xsmaddqp %0,%1,%2"
14183   [(set_attr "type" "vecfloat")
14184    (set_attr "size" "128")])
14186 (define_insn "*fms<mode>4_hw"
14187   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14188         (fma:IEEE128
14189          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14190          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14191          (neg:IEEE128
14192           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14193   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14194   "xsmsubqp %0,%1,%2"
14195   [(set_attr "type" "vecfloat")
14196    (set_attr "size" "128")])
14198 (define_insn "*nfma<mode>4_hw"
14199   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14200         (neg:IEEE128
14201          (fma:IEEE128
14202           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14203           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14204           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14205   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14206   "xsnmaddqp %0,%1,%2"
14207   [(set_attr "type" "vecfloat")
14208    (set_attr "size" "128")])
14210 (define_insn "*nfms<mode>4_hw"
14211   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14212         (neg:IEEE128
14213          (fma:IEEE128
14214           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14215           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14216           (neg:IEEE128
14217            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14218   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14219   "xsnmsubqp %0,%1,%2"
14220   [(set_attr "type" "vecfloat")
14221    (set_attr "size" "128")])
14223 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14224   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14225         (float_extend:IEEE128
14226          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14227   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14228   "xscvdpqp %0,%1"
14229   [(set_attr "type" "vecfloat")
14230    (set_attr "size" "128")])
14232 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14233 ;; point is a simple copy.
14234 (define_insn_and_split "extendkftf2"
14235   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14236         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14237   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14238   "@
14239    #
14240    xxlor %x0,%x1,%x1"
14241   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14242   [(const_int 0)]
14244   emit_note (NOTE_INSN_DELETED);
14245   DONE;
14247   [(set_attr "type" "*,veclogical")
14248    (set_attr "length" "0,4")])
14250 (define_insn_and_split "trunctfkf2"
14251   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14252         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14253   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14254   "@
14255    #
14256    xxlor %x0,%x1,%x1"
14257   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14258   [(const_int 0)]
14260   emit_note (NOTE_INSN_DELETED);
14261   DONE;
14263   [(set_attr "type" "*,veclogical")
14264    (set_attr "length" "0,4")])
14266 (define_insn "trunc<mode>df2_hw"
14267   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14268         (float_truncate:DF
14269          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14270   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14271   "xscvqpdp %0,%1"
14272   [(set_attr "type" "vecfloat")
14273    (set_attr "size" "128")])
14275 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14276 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14277 ;; conversion
14278 (define_insn_and_split "trunc<mode>sf2_hw"
14279   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14280         (float_truncate:SF
14281          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14282    (clobber (match_scratch:DF 2 "=v"))]
14283   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14284   "#"
14285   "&& 1"
14286   [(set (match_dup 2)
14287         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14288    (set (match_dup 0)
14289         (float_truncate:SF (match_dup 2)))]
14291   if (GET_CODE (operands[2]) == SCRATCH)
14292     operands[2] = gen_reg_rtx (DFmode);
14294   [(set_attr "type" "vecfloat")
14295    (set_attr "length" "8")])
14297 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
14298 ;; allowed in the traditional floating point registers. Use V2DImode so that
14299 ;; we can get a value in an Altivec register.
14301 (define_insn_and_split "fix<uns>_<mode>si2_hw"
14302   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
14303         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
14304    (clobber (match_scratch:V2DI 2 "=v,v"))]
14305   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14306   "#"
14307   "&& 1"
14308   [(pc)]
14310   convert_float128_to_int (operands, <CODE>);
14311   DONE;
14313   [(set_attr "length" "8")
14314    (set_attr "type" "mftgpr,fpstore")])
14316 (define_insn_and_split "fix<uns>_<mode>di2_hw"
14317   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
14318         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
14319    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14320   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14321   "#"
14322   "&& 1"
14323   [(pc)]
14325   convert_float128_to_int (operands, <CODE>);
14326   DONE;
14328   [(set_attr "length" "8")
14329    (set_attr "type" "mftgpr,vecsimple,fpstore")])
14331 (define_insn_and_split "float<uns>_<mode>si2_hw"
14332   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
14333         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
14334    (clobber (match_scratch:V2DI 2 "=v,v"))]
14335   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14336   "#"
14337   "&& 1"
14338   [(pc)]
14340   convert_int_to_float128 (operands, <CODE>);
14341   DONE;
14343   [(set_attr "length" "8")
14344    (set_attr "type" "vecfloat")])
14346 (define_insn_and_split "float<uns>_<mode>di2_hw"
14347   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14348         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
14349    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14350   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14351   "#"
14352   "&& 1"
14353   [(pc)]
14355   convert_int_to_float128 (operands, <CODE>);
14356   DONE;
14358   [(set_attr "length" "8")
14359    (set_attr "type" "vecfloat")])
14361 ;; Integer conversion instructions, using V2DImode to get an Altivec register
14362 (define_insn "*xscvqp<su>wz_<mode>"
14363   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14364         (unspec:V2DI
14365          [(any_fix:SI
14366            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14367          UNSPEC_IEEE128_CONVERT))]
14368   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14369   "xscvqp<su>wz %0,%1"
14370   [(set_attr "type" "vecfloat")
14371    (set_attr "size" "128")])
14373 (define_insn "*xscvqp<su>dz_<mode>"
14374   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14375         (unspec:V2DI
14376          [(any_fix:DI
14377            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14378          UNSPEC_IEEE128_CONVERT))]
14379   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14380   "xscvqp<su>dz %0,%1"
14381   [(set_attr "type" "vecfloat")
14382    (set_attr "size" "128")])
14384 (define_insn "*xscv<su>dqp_<mode>"
14385   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14386         (any_float:IEEE128
14387          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
14388                     UNSPEC_IEEE128_CONVERT)))]
14389   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14390   "xscv<su>dqp %0,%1"
14391   [(set_attr "type" "vecfloat")
14392    (set_attr "size" "128")])
14394 (define_insn "*ieee128_mfvsrd_64bit"
14395   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
14396         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
14397                    UNSPEC_IEEE128_MOVE))]
14398   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14399   "@
14400    mfvsrd %0,%x1
14401    stxsdx %x1,%y0
14402    xxlor %x0,%x1,%x1"
14403   [(set_attr "type" "mftgpr,fpstore,veclogical")])
14406 (define_insn "*ieee128_mfvsrd_32bit"
14407   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
14408         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14409                    UNSPEC_IEEE128_MOVE))]
14410   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14411   "@
14412    stxsdx %x1,%y0
14413    xxlor %x0,%x1,%x1"
14414   [(set_attr "type" "fpstore,veclogical")])
14416 (define_insn "*ieee128_mfvsrwz"
14417   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
14418         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14419                    UNSPEC_IEEE128_MOVE))]
14420   "TARGET_FLOAT128_HW"
14421   "@
14422    mfvsrwz %0,%x1
14423    stxsiwx %x1,%y0"
14424   [(set_attr "type" "mftgpr,fpstore")])
14426 ;; 0 says do sign-extension, 1 says zero-extension
14427 (define_insn "*ieee128_mtvsrw"
14428   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
14429         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
14430                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
14431                      UNSPEC_IEEE128_MOVE))]
14432   "TARGET_FLOAT128_HW"
14433   "@
14434    mtvsrwa %x0,%1
14435    lxsiwax %x0,%y1
14436    mtvsrwz %x0,%1
14437    lxsiwzx %x0,%y1"
14438   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
14441 (define_insn "*ieee128_mtvsrd_64bit"
14442   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
14443         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
14444                      UNSPEC_IEEE128_MOVE))]
14445   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14446   "@
14447    mtvsrd %x0,%1
14448    lxsdx %x0,%y1
14449    xxlor %x0,%x1,%x1"
14450   [(set_attr "type" "mffgpr,fpload,veclogical")])
14452 (define_insn "*ieee128_mtvsrd_32bit"
14453   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
14454         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
14455                      UNSPEC_IEEE128_MOVE))]
14456   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14457   "@
14458    lxsdx %x0,%y1
14459    xxlor %x0,%x1,%x1"
14460   [(set_attr "type" "fpload,veclogical")])
14462 ;; IEEE 128-bit instructions with round to odd semantics
14463 (define_insn "*trunc<mode>df2_odd"
14464   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14465         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14466                    UNSPEC_ROUND_TO_ODD))]
14467   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14468   "xscvqpdpo %0,%1"
14469   [(set_attr "type" "vecfloat")
14470    (set_attr "size" "128")])
14472 ;; IEEE 128-bit comparisons
14473 (define_insn "*cmp<mode>_hw"
14474   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14475         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14476                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14477   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14478    "xscmpuqp %0,%1,%2"
14479   [(set_attr "type" "veccmp")
14480    (set_attr "size" "128")])
14484 (include "sync.md")
14485 (include "vector.md")
14486 (include "vsx.md")
14487 (include "altivec.md")
14488 (include "spe.md")
14489 (include "dfp.md")
14490 (include "paired.md")
14491 (include "crypto.md")
14492 (include "htm.md")