[RS6000] Force source of fix_trunc<mode>si2 to reg
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob45ad66104fa814a051d517d941c1677b6fd39cbc
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2016 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (SPE_ACC_REGNO               111)
54    (SPEFSCR_REGNO               112)
55    (FRAME_POINTER_REGNUM        113)
56    (TFHAR_REGNO                 114)
57    (TFIAR_REGNO                 115)
58    (TEXASR_REGNO                116)
59    (FIRST_SPE_HIGH_REGNO        117)
60    (LAST_SPE_HIGH_REGNO         148)
61   ])
64 ;; UNSPEC usage
67 (define_c_enum "unspec"
68   [UNSPEC_FRSP                  ; frsp for POWER machines
69    UNSPEC_PROBE_STACK           ; probe stack memory reference
70    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
71    UNSPEC_TOC                   ; address of the TOC (more-or-less)
72    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
73    UNSPEC_MOVSI_GOT
74    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
75    UNSPEC_FCTIWZ
76    UNSPEC_FRIM
77    UNSPEC_FRIN
78    UNSPEC_FRIP
79    UNSPEC_FRIZ
80    UNSPEC_XSRDPI
81    UNSPEC_LD_MPIC               ; load_macho_picbase
82    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
83    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
84    UNSPEC_TLSGD
85    UNSPEC_TLSLD
86    UNSPEC_MOVESI_FROM_CR
87    UNSPEC_MOVESI_TO_CR
88    UNSPEC_TLSDTPREL
89    UNSPEC_TLSDTPRELHA
90    UNSPEC_TLSDTPRELLO
91    UNSPEC_TLSGOTDTPREL
92    UNSPEC_TLSTPREL
93    UNSPEC_TLSTPRELHA
94    UNSPEC_TLSTPRELLO
95    UNSPEC_TLSGOTTPREL
96    UNSPEC_TLSTLS
97    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
98    UNSPEC_MV_CR_GT              ; move_from_CR_gt_bit
99    UNSPEC_STFIWX
100    UNSPEC_POPCNTB
101    UNSPEC_FRES
102    UNSPEC_SP_SET
103    UNSPEC_SP_TEST
104    UNSPEC_SYNC
105    UNSPEC_LWSYNC
106    UNSPEC_SYNC_OP
107    UNSPEC_ATOMIC
108    UNSPEC_CMPXCHG
109    UNSPEC_XCHG
110    UNSPEC_AND
111    UNSPEC_DLMZB
112    UNSPEC_DLMZB_CR
113    UNSPEC_DLMZB_STRLEN
114    UNSPEC_RSQRT
115    UNSPEC_TOCREL
116    UNSPEC_MACHOPIC_OFFSET
117    UNSPEC_BPERM
118    UNSPEC_COPYSIGN
119    UNSPEC_PARITY
120    UNSPEC_FCTIW
121    UNSPEC_FCTID
122    UNSPEC_LFIWAX
123    UNSPEC_LFIWZX
124    UNSPEC_FCTIWUZ
125    UNSPEC_NOP
126    UNSPEC_GRP_END_NOP
127    UNSPEC_P8V_FMRGOW
128    UNSPEC_P8V_MTVSRWZ
129    UNSPEC_P8V_RELOAD_FROM_GPR
130    UNSPEC_P8V_MTVSRD
131    UNSPEC_P8V_XXPERMDI
132    UNSPEC_P8V_RELOAD_FROM_VSX
133    UNSPEC_ADDG6S
134    UNSPEC_CDTBCD
135    UNSPEC_CBCDTD
136    UNSPEC_DIVE
137    UNSPEC_DIVEO
138    UNSPEC_DIVEU
139    UNSPEC_DIVEUO
140    UNSPEC_UNPACK_128BIT
141    UNSPEC_PACK_128BIT
142    UNSPEC_LSQ
143    UNSPEC_FUSION_GPR
144    UNSPEC_STACK_CHECK
145    UNSPEC_FUSION_P9
146    UNSPEC_FUSION_ADDIS
147    UNSPEC_ROUND_TO_ODD
148    UNSPEC_IEEE128_MOVE
149    UNSPEC_IEEE128_CONVERT
150    UNSPEC_SIGNBIT
151    UNSPEC_DOLOOP
152   ])
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
159   [UNSPECV_BLOCK
160    UNSPECV_LL                   ; load-locked
161    UNSPECV_SC                   ; store-conditional
162    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
163    UNSPECV_EH_RR                ; eh_reg_restore
164    UNSPECV_ISYNC                ; isync instruction
165    UNSPECV_MFTB                 ; move from time base
166    UNSPECV_NLGR                 ; non-local goto receiver
167    UNSPECV_MFFS                 ; Move from FPSCR
168    UNSPECV_MTFSF                ; Move to FPSCR Fields
169    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
170   ])
173 ;; Define an insn type attribute.  This is used in function unit delay
174 ;; computations.
175 (define_attr "type"
176   "integer,two,three,
177    add,logical,shift,insert,
178    mul,halfmul,div,
179    exts,cntlz,popcnt,isel,
180    load,store,fpload,fpstore,vecload,vecstore,
181    cmp,
182    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
185    brinc,
186    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188    veclogical,veccmpfx,vecexts,vecmove,
189    htm,htmsimple,dfp"
190   (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that.  If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210   (if_then_else (ior (match_operand 0 "indexed_address_mem")
211                      (match_operand 1 "indexed_address_mem"))
212                 (const_string "yes")
213                 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns.  See the comments for "indexed".
217 (define_attr "update" "no,yes"
218   (if_then_else (ior (match_operand 0 "update_address_mem")
219                      (match_operand 1 "update_address_mem"))
220                 (const_string "yes")
221                 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
224 ;; register?
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231   (if_then_else (and (eq_attr "type" "shift")
232                      (eq_attr "maybe_var_shift" "yes"))
233                 (if_then_else (match_operand 2 "gpc_reg_operand")
234                               (const_string "yes")
235                               (const_string "no"))
236                 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248   (if_then_else (eq_attr "type" "branch")
249                 (if_then_else (and (ge (minus (match_dup 0) (pc))
250                                        (const_int -32768))
251                                    (lt (minus (match_dup 0) (pc))
252                                        (const_int 32764)))
253                               (const_int 4)
254                               (const_int 8))
255                 (const_int 4)))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
259 (define_attr "cpu"
260   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261    ppc750,ppc7400,ppc7450,
262    ppc403,ppc405,ppc440,ppc476,
263    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264    power4,power5,power6,power7,power8,power9,
265    rs64a,mpccore,cell,ppca2,titan"
266   (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273                           (eq_attr "dot" "yes"))
274                      (and (eq_attr "type" "load")
275                           (eq_attr "sign_extend" "yes"))
276                      (and (eq_attr "type" "shift")
277                           (eq_attr "var_shift" "yes")))
278                 (const_string "always")
279                 (const_string "not")))
281 (automata_option "ndfa")
283 (include "rs64.md")
284 (include "mpc.md")
285 (include "40x.md")
286 (include "440.md")
287 (include "476.md")
288 (include "601.md")
289 (include "603.md")
290 (include "6xx.md")
291 (include "7xx.md")
292 (include "7450.md")
293 (include "8540.md")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
297 (include "e5500.md")
298 (include "e6500.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
305 (include "cell.md")
306 (include "xfpu.md")
307 (include "a2.md")
308 (include "titan.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
316 ;; Mode iterators
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Everything we can extend QImode to.
329 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
331 ; Everything we can extend HImode to.
332 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend SImode to.
335 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
337 ; QImode or HImode for small atomic ops
338 (define_mode_iterator QHI [QI HI])
340 ; QImode, HImode, SImode for fused ops only for GPR loads
341 (define_mode_iterator QHSI [QI HI SI])
343 ; HImode or SImode for sign extended fusion ops
344 (define_mode_iterator HSI [HI SI])
346 ; SImode or DImode, even if DImode doesn't fit in GPRs.
347 (define_mode_iterator SDI [SI DI])
349 ; Types that can be fused with an ADDIS instruction to load or store a GPR
350 ; register that has reg+offset addressing.
351 (define_mode_iterator GPR_FUSION [QI
352                                   HI
353                                   SI
354                                   (DI   "TARGET_POWERPC64")
355                                   SF
356                                   (DF   "TARGET_POWERPC64")])
358 ; Types that can be fused with an ADDIS instruction to load or store a FPR
359 ; register that has reg+offset addressing.
360 (define_mode_iterator FPR_FUSION [DI SF DF])
362 ; The size of a pointer.  Also, the size of the value that a record-condition
363 ; (one with a '.') will compare; and the size used for arithmetic carries.
364 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
366 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
367 ; PTImode is GPR only)
368 (define_mode_iterator TI2 [TI PTI])
370 ; Any hardware-supported floating-point mode
371 (define_mode_iterator FP [
372   (SF "TARGET_HARD_FLOAT 
373    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
374   (DF "TARGET_HARD_FLOAT 
375    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
376   (TF "TARGET_HARD_FLOAT
377    && (TARGET_FPRS || TARGET_E500_DOUBLE)
378    && TARGET_LONG_DOUBLE_128")
379   (IF "TARGET_FLOAT128")
380   (KF "TARGET_FLOAT128")
381   (DD "TARGET_DFP")
382   (TD "TARGET_DFP")])
384 ; Any fma capable floating-point mode.
385 (define_mode_iterator FMA_F [
386   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
387   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
388        || VECTOR_UNIT_VSX_P (DFmode)")
389   (V2SF "TARGET_PAIRED_FLOAT")
390   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
391   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
392   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
393   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
394   ])
396 ; Floating point move iterators to combine binary and decimal moves
397 (define_mode_iterator FMOVE32 [SF SD])
398 (define_mode_iterator FMOVE64 [DF DD])
399 (define_mode_iterator FMOVE64X [DI DF DD])
400 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
401                                 (IF "TARGET_LONG_DOUBLE_128")
402                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
404 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
405                                     (IF "FLOAT128_2REG_P (IFmode)")
406                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
408 ; Iterators for 128 bit types for direct move
409 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
410                                     (V16QI "")
411                                     (V8HI  "")
412                                     (V4SI  "")
413                                     (V4SF  "")
414                                     (V2DI  "")
415                                     (V2DF  "")
416                                     (V1TI  "")
417                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
418                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
420 ; Iterator for 128-bit VSX types for pack/unpack
421 (define_mode_iterator FMOVE128_VSX [V1TI KF])
423 ; Whether a floating point move is ok, don't allow SD without hardware FP
424 (define_mode_attr fmove_ok [(SF "")
425                             (DF "")
426                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
427                             (DD "")])
429 ; Convert REAL_VALUE to the appropriate bits
430 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
431                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
432                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
433                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
435 ; Whether 0.0 has an all-zero bit pattern
436 (define_mode_attr zero_fp [(SF "j")
437                            (DF "j")
438                            (TF "j")
439                            (IF "j")
440                            (KF "j")
441                            (SD "wn")
442                            (DD "wn")
443                            (TD "wn")])
445 ; Definitions for load to 32-bit fpr register
446 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
447 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
448 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
449 (define_mode_attr f32_lm2 [(SF "o")               (SD "wn")])
450 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
451 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
452 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
454 ; Definitions for store from 32-bit fpr register
455 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
456 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
457 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
458 (define_mode_attr f32_sm2 [(SF "o")                (SD "wn")])
459 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
460 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
461 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwzx %x1,%y0")])
463 ; Definitions for 32-bit fpr direct move
464 ; At present, the decimal modes are not allowed in the traditional altivec
465 ; registers, so restrict the constraints to just the traditional FPRs.
466 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
468 ; Definitions for 32-bit VSX
469 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
471 ; Definitions for 32-bit use of altivec registers
472 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
474 ; Definitions for 64-bit VSX
475 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
477 ; Definitions for 64-bit direct move
478 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
480 ; Definitions for 64-bit use of altivec registers
481 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
483 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
484 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
486 ; These modes do not fit in integer registers in 32-bit mode.
487 ; but on e500v2, the gpr are 64 bit registers
488 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
490 ; Iterator for reciprocal estimate instructions
491 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
493 ; Iterator for just SF/DF
494 (define_mode_iterator SFDF [SF DF])
496 ; Like SFDF, but a different name to match conditional move where the
497 ; comparison operands may be a different mode than the input operands.
498 (define_mode_iterator SFDF2 [SF DF])
500 ; Iterator for 128-bit floating point that uses the IBM double-double format
501 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
502                               (TF "FLOAT128_IBM_P (TFmode)")])
504 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
505 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
506                                (TF "FLOAT128_IEEE_P (TFmode)")])
508 ; Iterator for 128-bit floating point
509 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
510                                 (IF "TARGET_FLOAT128")
511                                 (TF "TARGET_LONG_DOUBLE_128")])
513 ; Iterator for signbit on 64-bit machines with direct move
514 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
515                                (TF "FLOAT128_VECTOR_P (TFmode)")])
517 (define_mode_attr Fsignbit      [(KF "wa")
518                                  (TF "wa")])
520 ; Iterator for ISA 3.0 supported floating point types
521 (define_mode_iterator FP_ISA3 [SF
522                                DF
523                                (KF "FLOAT128_IEEE_P (KFmode)")
524                                (TF "FLOAT128_IEEE_P (TFmode)")])
526 ; SF/DF suffix for traditional floating instructions
527 (define_mode_attr Ftrad         [(SF "s") (DF "")])
529 ; SF/DF suffix for VSX instructions
530 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
532 ; SF/DF constraint for arithmetic on traditional floating point registers
533 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
535 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
536 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
537 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
538 ; format.
539 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
541 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
542 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
543 ; instructions added in ISA 2.07 (power8)
544 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
546 ; SF/DF constraint for arithmetic on altivec registers
547 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
549 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
550 (define_mode_attr Fs            [(SF "s")  (DF "d")])
552 ; FRE/FRES support
553 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
554 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
556 ; Conditional returns.
557 (define_code_iterator any_return [return simple_return])
558 (define_code_attr return_pred [(return "direct_return ()")
559                                (simple_return "1")])
560 (define_code_attr return_str [(return "") (simple_return "simple_")])
562 ; Logical operators.
563 (define_code_iterator iorxor [ior xor])
565 ; Signed/unsigned variants of ops.
566 (define_code_iterator any_extend        [sign_extend zero_extend])
567 (define_code_iterator any_fix           [fix unsigned_fix])
568 (define_code_iterator any_float         [float unsigned_float])
570 (define_code_attr u  [(sign_extend      "")
571                       (zero_extend      "u")])
573 (define_code_attr su [(sign_extend      "s")
574                       (zero_extend      "u")
575                       (fix              "s")
576                       (unsigned_fix     "s")
577                       (float            "s")
578                       (unsigned_float   "u")])
580 (define_code_attr az [(sign_extend      "a")
581                       (zero_extend      "z")
582                       (fix              "a")
583                       (unsigned_fix     "z")
584                       (float            "a")
585                       (unsigned_float   "z")])
587 (define_code_attr uns [(fix             "")
588                        (unsigned_fix    "uns")
589                        (float           "")
590                        (unsigned_float  "uns")])
592 ; Various instructions that come in SI and DI forms.
593 ; A generic w/d attribute, for things like cmpw/cmpd.
594 (define_mode_attr wd [(QI    "b")
595                       (HI    "h")
596                       (SI    "w")
597                       (DI    "d")
598                       (V16QI "b")
599                       (V8HI  "h")
600                       (V4SI  "w")
601                       (V2DI  "d")
602                       (V1TI  "q")
603                       (TI    "q")])
605 ;; How many bits in this mode?
606 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
608 ; DImode bits
609 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
611 ;; ISEL/ISEL64 target selection
612 (define_mode_attr sel [(SI "") (DI "64")])
614 ;; Bitmask for shift instructions
615 (define_mode_attr hH [(SI "h") (DI "H")])
617 ;; A mode twice the size of the given mode
618 (define_mode_attr dmode [(SI "di") (DI "ti")])
619 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
621 ;; Suffix for reload patterns
622 (define_mode_attr ptrsize [(SI "32bit")
623                            (DI "64bit")])
625 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
626                             (DI "TARGET_64BIT")])
628 (define_mode_attr mptrsize [(SI "si")
629                             (DI "di")])
631 (define_mode_attr ptrload [(SI "lwz")
632                            (DI "ld")])
634 (define_mode_attr ptrm [(SI "m")
635                         (DI "Y")])
637 (define_mode_attr rreg [(SF   "f")
638                         (DF   "ws")
639                         (TF   "f")
640                         (TD   "f")
641                         (V4SF "wf")
642                         (V2DF "wd")])
644 (define_mode_attr rreg2 [(SF   "f")
645                          (DF   "d")])
647 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
648                                  (DF "TARGET_FCFID")])
650 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
651                                 (DF "TARGET_E500_DOUBLE")])
653 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
654                                 (DF "TARGET_DOUBLE_FLOAT")])
656 ;; Mode iterator for logical operations on 128-bit types
657 (define_mode_iterator BOOL_128          [TI
658                                          PTI
659                                          (V16QI "TARGET_ALTIVEC")
660                                          (V8HI  "TARGET_ALTIVEC")
661                                          (V4SI  "TARGET_ALTIVEC")
662                                          (V4SF  "TARGET_ALTIVEC")
663                                          (V2DI  "TARGET_ALTIVEC")
664                                          (V2DF  "TARGET_ALTIVEC")
665                                          (V1TI  "TARGET_ALTIVEC")])
667 ;; For the GPRs we use 3 constraints for register outputs, two that are the
668 ;; same as the output register, and a third where the output register is an
669 ;; early clobber, so we don't have to deal with register overlaps.  For the
670 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
671 ;; either.
673 ;; Mode attribute for boolean operation register constraints for output
674 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
675                                          (PTI   "&r,r,r")
676                                          (V16QI "wa,v,&?r,?r,?r")
677                                          (V8HI  "wa,v,&?r,?r,?r")
678                                          (V4SI  "wa,v,&?r,?r,?r")
679                                          (V4SF  "wa,v,&?r,?r,?r")
680                                          (V2DI  "wa,v,&?r,?r,?r")
681                                          (V2DF  "wa,v,&?r,?r,?r")
682                                          (V1TI  "wa,v,&?r,?r,?r")])
684 ;; Mode attribute for boolean operation register constraints for operand1
685 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
686                                          (PTI   "r,0,r")
687                                          (V16QI "wa,v,r,0,r")
688                                          (V8HI  "wa,v,r,0,r")
689                                          (V4SI  "wa,v,r,0,r")
690                                          (V4SF  "wa,v,r,0,r")
691                                          (V2DI  "wa,v,r,0,r")
692                                          (V2DF  "wa,v,r,0,r")
693                                          (V1TI  "wa,v,r,0,r")])
695 ;; Mode attribute for boolean operation register constraints for operand2
696 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
697                                          (PTI   "r,r,0")
698                                          (V16QI "wa,v,r,r,0")
699                                          (V8HI  "wa,v,r,r,0")
700                                          (V4SI  "wa,v,r,r,0")
701                                          (V4SF  "wa,v,r,r,0")
702                                          (V2DI  "wa,v,r,r,0")
703                                          (V2DF  "wa,v,r,r,0")
704                                          (V1TI  "wa,v,r,r,0")])
706 ;; Mode attribute for boolean operation register constraints for operand1
707 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
708 ;; is used for operand1 or operand2
709 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
710                                          (PTI   "r,0,0")
711                                          (V16QI "wa,v,r,0,0")
712                                          (V8HI  "wa,v,r,0,0")
713                                          (V4SI  "wa,v,r,0,0")
714                                          (V4SF  "wa,v,r,0,0")
715                                          (V2DI  "wa,v,r,0,0")
716                                          (V2DF  "wa,v,r,0,0")
717                                          (V1TI  "wa,v,r,0,0")])
719 ;; Reload iterator for creating the function to allocate a base register to
720 ;; supplement addressing modes.
721 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
722                               SF SD SI DF DD DI TI PTI KF IF TF])
724 ;; Iterate over smin, smax
725 (define_code_iterator fp_minmax [smin smax])
727 (define_code_attr     minmax    [(smin "min")
728                                  (smax "max")])
730 (define_code_attr     SMINMAX   [(smin "SMIN")
731                                  (smax "SMAX")])
734 ;; Start with fixed-point load and store insns.  Here we put only the more
735 ;; complex forms.  Basic data transfer is done later.
737 (define_insn "zero_extendqi<mode>2"
738   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
739         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
740   ""
741   "@
742    lbz%U1%X1 %0,%1
743    rlwinm %0,%1,0,0xff"
744   [(set_attr "type" "load,shift")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot"
747   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
749                     (const_int 0)))
750    (clobber (match_scratch:EXTQI 0 "=r,r"))]
751   "rs6000_gen_cell_microcode"
752   "@
753    andi. %0,%1,0xff
754    #"
755   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
756   [(set (match_dup 0)
757         (zero_extend:EXTQI (match_dup 1)))
758    (set (match_dup 2)
759         (compare:CC (match_dup 0)
760                     (const_int 0)))]
761   ""
762   [(set_attr "type" "logical")
763    (set_attr "dot" "yes")
764    (set_attr "length" "4,8")])
766 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
767   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
769                     (const_int 0)))
770    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
771         (zero_extend:EXTQI (match_dup 1)))]
772   "rs6000_gen_cell_microcode"
773   "@
774    andi. %0,%1,0xff
775    #"
776   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
777   [(set (match_dup 0)
778         (zero_extend:EXTQI (match_dup 1)))
779    (set (match_dup 2)
780         (compare:CC (match_dup 0)
781                     (const_int 0)))]
782   ""
783   [(set_attr "type" "logical")
784    (set_attr "dot" "yes")
785    (set_attr "length" "4,8")])
788 (define_insn "zero_extendhi<mode>2"
789   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
790         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
791   ""
792   "@
793    lhz%U1%X1 %0,%1
794    rlwinm %0,%1,0,0xffff"
795   [(set_attr "type" "load,shift")])
797 (define_insn_and_split "*zero_extendhi<mode>2_dot"
798   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
800                     (const_int 0)))
801    (clobber (match_scratch:EXTHI 0 "=r,r"))]
802   "rs6000_gen_cell_microcode"
803   "@
804    andi. %0,%1,0xffff
805    #"
806   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
807   [(set (match_dup 0)
808         (zero_extend:EXTHI (match_dup 1)))
809    (set (match_dup 2)
810         (compare:CC (match_dup 0)
811                     (const_int 0)))]
812   ""
813   [(set_attr "type" "logical")
814    (set_attr "dot" "yes")
815    (set_attr "length" "4,8")])
817 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
818   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
819         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
820                     (const_int 0)))
821    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
822         (zero_extend:EXTHI (match_dup 1)))]
823   "rs6000_gen_cell_microcode"
824   "@
825    andi. %0,%1,0xffff
826    #"
827   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
828   [(set (match_dup 0)
829         (zero_extend:EXTHI (match_dup 1)))
830    (set (match_dup 2)
831         (compare:CC (match_dup 0)
832                     (const_int 0)))]
833   ""
834   [(set_attr "type" "logical")
835    (set_attr "dot" "yes")
836    (set_attr "length" "4,8")])
839 (define_insn "zero_extendsi<mode>2"
840   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
841         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
842   ""
843   "@
844    lwz%U1%X1 %0,%1
845    rldicl %0,%1,0,32
846    mtvsrwz %x0,%1
847    lfiwzx %0,%y1
848    lxsiwzx %x0,%y1"
849   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
851 (define_insn_and_split "*zero_extendsi<mode>2_dot"
852   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
854                     (const_int 0)))
855    (clobber (match_scratch:EXTSI 0 "=r,r"))]
856   "rs6000_gen_cell_microcode"
857   "@
858    rldicl. %0,%1,0,32
859    #"
860   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
861   [(set (match_dup 0)
862         (zero_extend:DI (match_dup 1)))
863    (set (match_dup 2)
864         (compare:CC (match_dup 0)
865                     (const_int 0)))]
866   ""
867   [(set_attr "type" "shift")
868    (set_attr "dot" "yes")
869    (set_attr "length" "4,8")])
871 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
872   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
873         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
874                     (const_int 0)))
875    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
876         (zero_extend:EXTSI (match_dup 1)))]
877   "rs6000_gen_cell_microcode"
878   "@
879    rldicl. %0,%1,0,32
880    #"
881   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
882   [(set (match_dup 0)
883         (zero_extend:EXTSI (match_dup 1)))
884    (set (match_dup 2)
885         (compare:CC (match_dup 0)
886                     (const_int 0)))]
887   ""
888   [(set_attr "type" "shift")
889    (set_attr "dot" "yes")
890    (set_attr "length" "4,8")])
893 (define_insn "extendqi<mode>2"
894   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
895         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
896   ""
897   "extsb %0,%1"
898   [(set_attr "type" "exts")])
900 (define_insn_and_split "*extendqi<mode>2_dot"
901   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
902         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
903                     (const_int 0)))
904    (clobber (match_scratch:EXTQI 0 "=r,r"))]
905   "rs6000_gen_cell_microcode"
906   "@
907    extsb. %0,%1
908    #"
909   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
910   [(set (match_dup 0)
911         (sign_extend:EXTQI (match_dup 1)))
912    (set (match_dup 2)
913         (compare:CC (match_dup 0)
914                     (const_int 0)))]
915   ""
916   [(set_attr "type" "exts")
917    (set_attr "dot" "yes")
918    (set_attr "length" "4,8")])
920 (define_insn_and_split "*extendqi<mode>2_dot2"
921   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
922         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
923                     (const_int 0)))
924    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
925         (sign_extend:EXTQI (match_dup 1)))]
926   "rs6000_gen_cell_microcode"
927   "@
928    extsb. %0,%1
929    #"
930   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
931   [(set (match_dup 0)
932         (sign_extend:EXTQI (match_dup 1)))
933    (set (match_dup 2)
934         (compare:CC (match_dup 0)
935                     (const_int 0)))]
936   ""
937   [(set_attr "type" "exts")
938    (set_attr "dot" "yes")
939    (set_attr "length" "4,8")])
942 (define_expand "extendhi<mode>2"
943   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
944         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
945   ""
946   "")
948 (define_insn "*extendhi<mode>2"
949   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
950         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
951   "rs6000_gen_cell_microcode"
952   "@
953    lha%U1%X1 %0,%1
954    extsh %0,%1"
955   [(set_attr "type" "load,exts")
956    (set_attr "sign_extend" "yes")])
958 (define_insn "*extendhi<mode>2_noload"
959   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
960         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
961   "!rs6000_gen_cell_microcode"
962   "extsh %0,%1"
963   [(set_attr "type" "exts")])
965 (define_insn_and_split "*extendhi<mode>2_dot"
966   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
967         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
968                     (const_int 0)))
969    (clobber (match_scratch:EXTHI 0 "=r,r"))]
970   "rs6000_gen_cell_microcode"
971   "@
972    extsh. %0,%1
973    #"
974   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
975   [(set (match_dup 0)
976         (sign_extend:EXTHI (match_dup 1)))
977    (set (match_dup 2)
978         (compare:CC (match_dup 0)
979                     (const_int 0)))]
980   ""
981   [(set_attr "type" "exts")
982    (set_attr "dot" "yes")
983    (set_attr "length" "4,8")])
985 (define_insn_and_split "*extendhi<mode>2_dot2"
986   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
987         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
988                     (const_int 0)))
989    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
990         (sign_extend:EXTHI (match_dup 1)))]
991   "rs6000_gen_cell_microcode"
992   "@
993    extsh. %0,%1
994    #"
995   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
996   [(set (match_dup 0)
997         (sign_extend:EXTHI (match_dup 1)))
998    (set (match_dup 2)
999         (compare:CC (match_dup 0)
1000                     (const_int 0)))]
1001   ""
1002   [(set_attr "type" "exts")
1003    (set_attr "dot" "yes")
1004    (set_attr "length" "4,8")])
1007 (define_insn "extendsi<mode>2"
1008   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
1009         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
1010   ""
1011   "@
1012    lwa%U1%X1 %0,%1
1013    extsw %0,%1
1014    mtvsrwa %x0,%1
1015    lfiwax %0,%y1
1016    lxsiwax %x0,%y1"
1017   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
1018    (set_attr "sign_extend" "yes")])
1020 (define_insn_and_split "*extendsi<mode>2_dot"
1021   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1022         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1023                     (const_int 0)))
1024    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1025   "rs6000_gen_cell_microcode"
1026   "@
1027    extsw. %0,%1
1028    #"
1029   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1030   [(set (match_dup 0)
1031         (sign_extend:EXTSI (match_dup 1)))
1032    (set (match_dup 2)
1033         (compare:CC (match_dup 0)
1034                     (const_int 0)))]
1035   ""
1036   [(set_attr "type" "exts")
1037    (set_attr "dot" "yes")
1038    (set_attr "length" "4,8")])
1040 (define_insn_and_split "*extendsi<mode>2_dot2"
1041   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1042         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1043                     (const_int 0)))
1044    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1045         (sign_extend:EXTSI (match_dup 1)))]
1046   "rs6000_gen_cell_microcode"
1047   "@
1048    extsw. %0,%1
1049    #"
1050   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1051   [(set (match_dup 0)
1052         (sign_extend:EXTSI (match_dup 1)))
1053    (set (match_dup 2)
1054         (compare:CC (match_dup 0)
1055                     (const_int 0)))]
1056   ""
1057   [(set_attr "type" "exts")
1058    (set_attr "dot" "yes")
1059    (set_attr "length" "4,8")])
1061 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1063 (define_insn "*macchwc"
1064   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1066                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1067                                        (const_int 16))
1068                                       (sign_extend:SI
1069                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1070                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1071                     (const_int 0)))
1072    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1073         (plus:SI (mult:SI (ashiftrt:SI
1074                            (match_dup 2)
1075                            (const_int 16))
1076                           (sign_extend:SI
1077                            (match_dup 1)))
1078                  (match_dup 4)))]
1079   "TARGET_MULHW"
1080   "macchw. %0,%1,%2"
1081   [(set_attr "type" "halfmul")])
1083 (define_insn "*macchw"
1084   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1085         (plus:SI (mult:SI (ashiftrt:SI
1086                            (match_operand:SI 2 "gpc_reg_operand" "r")
1087                            (const_int 16))
1088                           (sign_extend:SI
1089                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1090                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1091   "TARGET_MULHW"
1092   "macchw %0,%1,%2"
1093   [(set_attr "type" "halfmul")])
1095 (define_insn "*macchwuc"
1096   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1097         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1098                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1099                                        (const_int 16))
1100                                       (zero_extend:SI
1101                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1102                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1103                     (const_int 0)))
1104    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1105         (plus:SI (mult:SI (lshiftrt:SI
1106                            (match_dup 2)
1107                            (const_int 16))
1108                           (zero_extend:SI
1109                            (match_dup 1)))
1110                  (match_dup 4)))]
1111   "TARGET_MULHW"
1112   "macchwu. %0,%1,%2"
1113   [(set_attr "type" "halfmul")])
1115 (define_insn "*macchwu"
1116   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1117         (plus:SI (mult:SI (lshiftrt:SI
1118                            (match_operand:SI 2 "gpc_reg_operand" "r")
1119                            (const_int 16))
1120                           (zero_extend:SI
1121                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1122                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1123   "TARGET_MULHW"
1124   "macchwu %0,%1,%2"
1125   [(set_attr "type" "halfmul")])
1127 (define_insn "*machhwc"
1128   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1129         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1130                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1131                                        (const_int 16))
1132                                       (ashiftrt:SI
1133                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1134                                        (const_int 16)))
1135                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1136                     (const_int 0)))
1137    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1138         (plus:SI (mult:SI (ashiftrt:SI
1139                            (match_dup 1)
1140                            (const_int 16))
1141                           (ashiftrt:SI
1142                            (match_dup 2)
1143                            (const_int 16)))
1144                  (match_dup 4)))]
1145   "TARGET_MULHW"
1146   "machhw. %0,%1,%2"
1147   [(set_attr "type" "halfmul")])
1149 (define_insn "*machhw"
1150   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1151         (plus:SI (mult:SI (ashiftrt:SI
1152                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1153                            (const_int 16))
1154                           (ashiftrt:SI
1155                            (match_operand:SI 2 "gpc_reg_operand" "r")
1156                            (const_int 16)))
1157                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1158   "TARGET_MULHW"
1159   "machhw %0,%1,%2"
1160   [(set_attr "type" "halfmul")])
1162 (define_insn "*machhwuc"
1163   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1164         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1165                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1166                                        (const_int 16))
1167                                       (lshiftrt:SI
1168                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1169                                        (const_int 16)))
1170                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1171                     (const_int 0)))
1172    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1173         (plus:SI (mult:SI (lshiftrt:SI
1174                            (match_dup 1)
1175                            (const_int 16))
1176                           (lshiftrt:SI
1177                            (match_dup 2)
1178                            (const_int 16)))
1179                  (match_dup 4)))]
1180   "TARGET_MULHW"
1181   "machhwu. %0,%1,%2"
1182   [(set_attr "type" "halfmul")])
1184 (define_insn "*machhwu"
1185   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186         (plus:SI (mult:SI (lshiftrt:SI
1187                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1188                            (const_int 16))
1189                           (lshiftrt:SI
1190                            (match_operand:SI 2 "gpc_reg_operand" "r")
1191                            (const_int 16)))
1192                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1193   "TARGET_MULHW"
1194   "machhwu %0,%1,%2"
1195   [(set_attr "type" "halfmul")])
1197 (define_insn "*maclhwc"
1198   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1199         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1200                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1201                                       (sign_extend:SI
1202                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1203                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1204                     (const_int 0)))
1205    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1206         (plus:SI (mult:SI (sign_extend:SI
1207                            (match_dup 1))
1208                           (sign_extend:SI
1209                            (match_dup 2)))
1210                  (match_dup 4)))]
1211   "TARGET_MULHW"
1212   "maclhw. %0,%1,%2"
1213   [(set_attr "type" "halfmul")])
1215 (define_insn "*maclhw"
1216   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1217         (plus:SI (mult:SI (sign_extend:SI
1218                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1219                           (sign_extend:SI
1220                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1221                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1222   "TARGET_MULHW"
1223   "maclhw %0,%1,%2"
1224   [(set_attr "type" "halfmul")])
1226 (define_insn "*maclhwuc"
1227   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1229                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1230                                       (zero_extend:SI
1231                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1232                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1233                     (const_int 0)))
1234    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235         (plus:SI (mult:SI (zero_extend:SI
1236                            (match_dup 1))
1237                           (zero_extend:SI
1238                            (match_dup 2)))
1239                  (match_dup 4)))]
1240   "TARGET_MULHW"
1241   "maclhwu. %0,%1,%2"
1242   [(set_attr "type" "halfmul")])
1244 (define_insn "*maclhwu"
1245   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246         (plus:SI (mult:SI (zero_extend:SI
1247                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1248                           (zero_extend:SI
1249                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1250                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1251   "TARGET_MULHW"
1252   "maclhwu %0,%1,%2"
1253   [(set_attr "type" "halfmul")])
1255 (define_insn "*nmacchwc"
1256   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1258                               (mult:SI (ashiftrt:SI
1259                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1260                                         (const_int 16))
1261                                        (sign_extend:SI
1262                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1263                     (const_int 0)))
1264    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265         (minus:SI (match_dup 4)
1266                   (mult:SI (ashiftrt:SI
1267                             (match_dup 2)
1268                             (const_int 16))
1269                            (sign_extend:SI
1270                             (match_dup 1)))))]
1271   "TARGET_MULHW"
1272   "nmacchw. %0,%1,%2"
1273   [(set_attr "type" "halfmul")])
1275 (define_insn "*nmacchw"
1276   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1277         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1278                   (mult:SI (ashiftrt:SI
1279                             (match_operand:SI 2 "gpc_reg_operand" "r")
1280                             (const_int 16))
1281                            (sign_extend:SI
1282                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1283   "TARGET_MULHW"
1284   "nmacchw %0,%1,%2"
1285   [(set_attr "type" "halfmul")])
1287 (define_insn "*nmachhwc"
1288   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1289         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1290                               (mult:SI (ashiftrt:SI
1291                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1292                                         (const_int 16))
1293                                        (ashiftrt:SI
1294                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1295                                         (const_int 16))))
1296                     (const_int 0)))
1297    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1298         (minus:SI (match_dup 4)
1299                   (mult:SI (ashiftrt:SI
1300                             (match_dup 1)
1301                             (const_int 16))
1302                            (ashiftrt:SI
1303                             (match_dup 2)
1304                             (const_int 16)))))]
1305   "TARGET_MULHW"
1306   "nmachhw. %0,%1,%2"
1307   [(set_attr "type" "halfmul")])
1309 (define_insn "*nmachhw"
1310   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1311         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1312                   (mult:SI (ashiftrt:SI
1313                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1314                             (const_int 16))
1315                            (ashiftrt:SI
1316                             (match_operand:SI 2 "gpc_reg_operand" "r")
1317                             (const_int 16)))))]
1318   "TARGET_MULHW"
1319   "nmachhw %0,%1,%2"
1320   [(set_attr "type" "halfmul")])
1322 (define_insn "*nmaclhwc"
1323   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1324         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1325                               (mult:SI (sign_extend:SI
1326                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1327                                        (sign_extend:SI
1328                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1329                     (const_int 0)))
1330    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1331         (minus:SI (match_dup 4)
1332                   (mult:SI (sign_extend:SI
1333                             (match_dup 1))
1334                            (sign_extend:SI
1335                             (match_dup 2)))))]
1336   "TARGET_MULHW"
1337   "nmaclhw. %0,%1,%2"
1338   [(set_attr "type" "halfmul")])
1340 (define_insn "*nmaclhw"
1341   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1342         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1343                   (mult:SI (sign_extend:SI
1344                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1345                            (sign_extend:SI
1346                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1347   "TARGET_MULHW"
1348   "nmaclhw %0,%1,%2"
1349   [(set_attr "type" "halfmul")])
1351 (define_insn "*mulchwc"
1352   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353         (compare:CC (mult:SI (ashiftrt:SI
1354                               (match_operand:SI 2 "gpc_reg_operand" "r")
1355                               (const_int 16))
1356                              (sign_extend:SI
1357                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1358                     (const_int 0)))
1359    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1360         (mult:SI (ashiftrt:SI
1361                   (match_dup 2)
1362                   (const_int 16))
1363                  (sign_extend:SI
1364                   (match_dup 1))))]
1365   "TARGET_MULHW"
1366   "mulchw. %0,%1,%2"
1367   [(set_attr "type" "halfmul")])
1369 (define_insn "*mulchw"
1370   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371         (mult:SI (ashiftrt:SI
1372                   (match_operand:SI 2 "gpc_reg_operand" "r")
1373                   (const_int 16))
1374                  (sign_extend:SI
1375                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1376   "TARGET_MULHW"
1377   "mulchw %0,%1,%2"
1378   [(set_attr "type" "halfmul")])
1380 (define_insn "*mulchwuc"
1381   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1382         (compare:CC (mult:SI (lshiftrt:SI
1383                               (match_operand:SI 2 "gpc_reg_operand" "r")
1384                               (const_int 16))
1385                              (zero_extend:SI
1386                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1387                     (const_int 0)))
1388    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389         (mult:SI (lshiftrt:SI
1390                   (match_dup 2)
1391                   (const_int 16))
1392                  (zero_extend:SI
1393                   (match_dup 1))))]
1394   "TARGET_MULHW"
1395   "mulchwu. %0,%1,%2"
1396   [(set_attr "type" "halfmul")])
1398 (define_insn "*mulchwu"
1399   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400         (mult:SI (lshiftrt:SI
1401                   (match_operand:SI 2 "gpc_reg_operand" "r")
1402                   (const_int 16))
1403                  (zero_extend:SI
1404                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1405   "TARGET_MULHW"
1406   "mulchwu %0,%1,%2"
1407   [(set_attr "type" "halfmul")])
1409 (define_insn "*mulhhwc"
1410   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411         (compare:CC (mult:SI (ashiftrt:SI
1412                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1413                               (const_int 16))
1414                              (ashiftrt:SI
1415                               (match_operand:SI 2 "gpc_reg_operand" "r")
1416                               (const_int 16)))
1417                     (const_int 0)))
1418    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419         (mult:SI (ashiftrt:SI
1420                   (match_dup 1)
1421                   (const_int 16))
1422                  (ashiftrt:SI
1423                   (match_dup 2)
1424                   (const_int 16))))]
1425   "TARGET_MULHW"
1426   "mulhhw. %0,%1,%2"
1427   [(set_attr "type" "halfmul")])
1429 (define_insn "*mulhhw"
1430   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1431         (mult:SI (ashiftrt:SI
1432                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1433                   (const_int 16))
1434                  (ashiftrt:SI
1435                   (match_operand:SI 2 "gpc_reg_operand" "r")
1436                   (const_int 16))))]
1437   "TARGET_MULHW"
1438   "mulhhw %0,%1,%2"
1439   [(set_attr "type" "halfmul")])
1441 (define_insn "*mulhhwuc"
1442   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1443         (compare:CC (mult:SI (lshiftrt:SI
1444                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1445                               (const_int 16))
1446                              (lshiftrt:SI
1447                               (match_operand:SI 2 "gpc_reg_operand" "r")
1448                               (const_int 16)))
1449                     (const_int 0)))
1450    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451         (mult:SI (lshiftrt:SI
1452                   (match_dup 1)
1453                   (const_int 16))
1454                  (lshiftrt:SI
1455                   (match_dup 2)
1456                   (const_int 16))))]
1457   "TARGET_MULHW"
1458   "mulhhwu. %0,%1,%2"
1459   [(set_attr "type" "halfmul")])
1461 (define_insn "*mulhhwu"
1462   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1463         (mult:SI (lshiftrt:SI
1464                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1465                   (const_int 16))
1466                  (lshiftrt:SI
1467                   (match_operand:SI 2 "gpc_reg_operand" "r")
1468                   (const_int 16))))]
1469   "TARGET_MULHW"
1470   "mulhhwu %0,%1,%2"
1471   [(set_attr "type" "halfmul")])
1473 (define_insn "*mullhwc"
1474   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1475         (compare:CC (mult:SI (sign_extend:SI
1476                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1477                              (sign_extend:SI
1478                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1479                     (const_int 0)))
1480    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1481         (mult:SI (sign_extend:SI
1482                   (match_dup 1))
1483                  (sign_extend:SI
1484                   (match_dup 2))))]
1485   "TARGET_MULHW"
1486   "mullhw. %0,%1,%2"
1487   [(set_attr "type" "halfmul")])
1489 (define_insn "*mullhw"
1490   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491         (mult:SI (sign_extend:SI
1492                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1493                  (sign_extend:SI
1494                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1495   "TARGET_MULHW"
1496   "mullhw %0,%1,%2"
1497   [(set_attr "type" "halfmul")])
1499 (define_insn "*mullhwuc"
1500   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1501         (compare:CC (mult:SI (zero_extend:SI
1502                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1503                              (zero_extend:SI
1504                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1505                     (const_int 0)))
1506    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507         (mult:SI (zero_extend:SI
1508                   (match_dup 1))
1509                  (zero_extend:SI
1510                   (match_dup 2))))]
1511   "TARGET_MULHW"
1512   "mullhwu. %0,%1,%2"
1513   [(set_attr "type" "halfmul")])
1515 (define_insn "*mullhwu"
1516   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517         (mult:SI (zero_extend:SI
1518                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1519                  (zero_extend:SI
1520                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1521   "TARGET_MULHW"
1522   "mullhwu %0,%1,%2"
1523   [(set_attr "type" "halfmul")])
1525 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1526 (define_insn "dlmzb"
1527   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1528         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1529                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1530                    UNSPEC_DLMZB_CR))
1531    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532         (unspec:SI [(match_dup 1)
1533                     (match_dup 2)]
1534                    UNSPEC_DLMZB))]
1535   "TARGET_DLMZB"
1536   "dlmzb. %0,%1,%2")
1538 (define_expand "strlensi"
1539   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1540         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1541                     (match_operand:QI 2 "const_int_operand" "")
1542                     (match_operand 3 "const_int_operand" "")]
1543                    UNSPEC_DLMZB_STRLEN))
1544    (clobber (match_scratch:CC 4 "=x"))]
1545   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1547   rtx result = operands[0];
1548   rtx src = operands[1];
1549   rtx search_char = operands[2];
1550   rtx align = operands[3];
1551   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1552   rtx loop_label, end_label, mem, cr0, cond;
1553   if (search_char != const0_rtx
1554       || GET_CODE (align) != CONST_INT
1555       || INTVAL (align) < 8)
1556         FAIL;
1557   word1 = gen_reg_rtx (SImode);
1558   word2 = gen_reg_rtx (SImode);
1559   scratch_dlmzb = gen_reg_rtx (SImode);
1560   scratch_string = gen_reg_rtx (Pmode);
1561   loop_label = gen_label_rtx ();
1562   end_label = gen_label_rtx ();
1563   addr = force_reg (Pmode, XEXP (src, 0));
1564   emit_move_insn (scratch_string, addr);
1565   emit_label (loop_label);
1566   mem = change_address (src, SImode, scratch_string);
1567   emit_move_insn (word1, mem);
1568   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1569   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1570   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1571   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1572   emit_jump_insn (gen_rtx_SET (pc_rtx,
1573                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1574                                                      cond,
1575                                                      gen_rtx_LABEL_REF
1576                                                        (VOIDmode,
1577                                                         end_label),
1578                                                      pc_rtx)));
1579   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1580   emit_jump_insn (gen_rtx_SET (pc_rtx,
1581                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1582   emit_barrier ();
1583   emit_label (end_label);
1584   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1585   emit_insn (gen_subsi3 (result, scratch_string, addr));
1586   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1587   DONE;
1590 ;; Fixed-point arithmetic insns.
1592 (define_expand "add<mode>3"
1593   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1594         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1595                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1596   ""
1598   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1599     {
1600       rtx lo0 = gen_lowpart (SImode, operands[0]);
1601       rtx lo1 = gen_lowpart (SImode, operands[1]);
1602       rtx lo2 = gen_lowpart (SImode, operands[2]);
1603       rtx hi0 = gen_highpart (SImode, operands[0]);
1604       rtx hi1 = gen_highpart (SImode, operands[1]);
1605       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1607       if (!reg_or_short_operand (lo2, SImode))
1608         lo2 = force_reg (SImode, lo2);
1609       if (!adde_operand (hi2, SImode))
1610         hi2 = force_reg (SImode, hi2);
1612       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1613       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1614       DONE;
1615     }
1617   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1618     {
1619       rtx tmp = ((!can_create_pseudo_p ()
1620                   || rtx_equal_p (operands[0], operands[1]))
1621                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1623       HOST_WIDE_INT val = INTVAL (operands[2]);
1624       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1625       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1627       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1628         FAIL;
1630       /* The ordering here is important for the prolog expander.
1631          When space is allocated from the stack, adding 'low' first may
1632          produce a temporary deallocation (which would be bad).  */
1633       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1634       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1635       DONE;
1636     }
1639 (define_insn "*add<mode>3"
1640   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1641         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1642                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1643   ""
1644   "@
1645    add %0,%1,%2
1646    addi %0,%1,%2
1647    addis %0,%1,%v2"
1648   [(set_attr "type" "add")])
1650 (define_insn "addsi3_high"
1651   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1652         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1653                  (high:SI (match_operand 2 "" ""))))]
1654   "TARGET_MACHO && !TARGET_64BIT"
1655   "addis %0,%1,ha16(%2)"
1656   [(set_attr "type" "add")])
1658 (define_insn_and_split "*add<mode>3_dot"
1659   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1660         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1661                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1662                     (const_int 0)))
1663    (clobber (match_scratch:GPR 0 "=r,r"))]
1664   "<MODE>mode == Pmode"
1665   "@
1666    add. %0,%1,%2
1667    #"
1668   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1669   [(set (match_dup 0)
1670         (plus:GPR (match_dup 1)
1671                  (match_dup 2)))
1672    (set (match_dup 3)
1673         (compare:CC (match_dup 0)
1674                     (const_int 0)))]
1675   ""
1676   [(set_attr "type" "add")
1677    (set_attr "dot" "yes")
1678    (set_attr "length" "4,8")])
1680 (define_insn_and_split "*add<mode>3_dot2"
1681   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1682         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1683                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1684                     (const_int 0)))
1685    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1686         (plus:GPR (match_dup 1)
1687                   (match_dup 2)))]
1688   "<MODE>mode == Pmode"
1689   "@
1690    add. %0,%1,%2
1691    #"
1692   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1693   [(set (match_dup 0)
1694         (plus:GPR (match_dup 1)
1695                   (match_dup 2)))
1696    (set (match_dup 3)
1697         (compare:CC (match_dup 0)
1698                     (const_int 0)))]
1699   ""
1700   [(set_attr "type" "add")
1701    (set_attr "dot" "yes")
1702    (set_attr "length" "4,8")])
1704 (define_insn_and_split "*add<mode>3_imm_dot"
1705   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1706         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1707                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1708                     (const_int 0)))
1709    (clobber (match_scratch:GPR 0 "=r,r"))
1710    (clobber (reg:GPR CA_REGNO))]
1711   "<MODE>mode == Pmode"
1712   "@
1713    addic. %0,%1,%2
1714    #"
1715   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1716   [(set (match_dup 0)
1717         (plus:GPR (match_dup 1)
1718                   (match_dup 2)))
1719    (set (match_dup 3)
1720         (compare:CC (match_dup 0)
1721                     (const_int 0)))]
1722   ""
1723   [(set_attr "type" "add")
1724    (set_attr "dot" "yes")
1725    (set_attr "length" "4,8")])
1727 (define_insn_and_split "*add<mode>3_imm_dot2"
1728   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1729         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1730                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1731                     (const_int 0)))
1732    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1733         (plus:GPR (match_dup 1)
1734                   (match_dup 2)))
1735    (clobber (reg:GPR CA_REGNO))]
1736   "<MODE>mode == Pmode"
1737   "@
1738    addic. %0,%1,%2
1739    #"
1740   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1741   [(set (match_dup 0)
1742         (plus:GPR (match_dup 1)
1743                   (match_dup 2)))
1744    (set (match_dup 3)
1745         (compare:CC (match_dup 0)
1746                     (const_int 0)))]
1747   ""
1748   [(set_attr "type" "add")
1749    (set_attr "dot" "yes")
1750    (set_attr "length" "4,8")])
1752 ;; Split an add that we can't do in one insn into two insns, each of which
1753 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1754 ;; add should be last in case the result gets used in an address.
1756 (define_split
1757   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1758         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1759                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1760   ""
1761   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1762    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1764   HOST_WIDE_INT val = INTVAL (operands[2]);
1765   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1766   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1768   operands[4] = GEN_INT (low);
1769   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1770     operands[3] = GEN_INT (rest);
1771   else if (can_create_pseudo_p ())
1772     {
1773       operands[3] = gen_reg_rtx (DImode);
1774       emit_move_insn (operands[3], operands[2]);
1775       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1776       DONE;
1777     }
1778   else
1779     FAIL;
1783 (define_insn "add<mode>3_carry"
1784   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1785         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1786                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1787    (set (reg:P CA_REGNO)
1788         (ltu:P (plus:P (match_dup 1)
1789                        (match_dup 2))
1790                (match_dup 1)))]
1791   ""
1792   "add%I2c %0,%1,%2"
1793   [(set_attr "type" "add")])
1795 (define_insn "*add<mode>3_imm_carry_pos"
1796   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1797         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1798                 (match_operand:P 2 "short_cint_operand" "n")))
1799    (set (reg:P CA_REGNO)
1800         (geu:P (match_dup 1)
1801                (match_operand:P 3 "const_int_operand" "n")))]
1802   "INTVAL (operands[2]) > 0
1803    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1804   "addic %0,%1,%2"
1805   [(set_attr "type" "add")])
1807 (define_insn "*add<mode>3_imm_carry_0"
1808   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1809         (match_operand:P 1 "gpc_reg_operand" "r"))
1810    (set (reg:P CA_REGNO)
1811         (const_int 0))]
1812   ""
1813   "addic %0,%1,0"
1814   [(set_attr "type" "add")])
1816 (define_insn "*add<mode>3_imm_carry_m1"
1817   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1818         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1819                 (const_int -1)))
1820    (set (reg:P CA_REGNO)
1821         (ne:P (match_dup 1)
1822               (const_int 0)))]
1823   ""
1824   "addic %0,%1,-1"
1825   [(set_attr "type" "add")])
1827 (define_insn "*add<mode>3_imm_carry_neg"
1828   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1829         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1830                 (match_operand:P 2 "short_cint_operand" "n")))
1831    (set (reg:P CA_REGNO)
1832         (gtu:P (match_dup 1)
1833                (match_operand:P 3 "const_int_operand" "n")))]
1834   "INTVAL (operands[2]) < 0
1835    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1836   "addic %0,%1,%2"
1837   [(set_attr "type" "add")])
1840 (define_expand "add<mode>3_carry_in"
1841   [(parallel [
1842      (set (match_operand:GPR 0 "gpc_reg_operand")
1843           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1844                               (match_operand:GPR 2 "adde_operand"))
1845                     (reg:GPR CA_REGNO)))
1846      (clobber (reg:GPR CA_REGNO))])]
1847   ""
1849   if (operands[2] == const0_rtx)
1850     {
1851       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1852       DONE;
1853     }
1854   if (operands[2] == constm1_rtx)
1855     {
1856       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1857       DONE;
1858     }
1861 (define_insn "*add<mode>3_carry_in_internal"
1862   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1863         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1864                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1865                   (reg:GPR CA_REGNO)))
1866    (clobber (reg:GPR CA_REGNO))]
1867   ""
1868   "adde %0,%1,%2"
1869   [(set_attr "type" "add")])
1871 (define_insn "add<mode>3_carry_in_0"
1872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1873         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1874                   (reg:GPR CA_REGNO)))
1875    (clobber (reg:GPR CA_REGNO))]
1876   ""
1877   "addze %0,%1"
1878   [(set_attr "type" "add")])
1880 (define_insn "add<mode>3_carry_in_m1"
1881   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1882         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1883                             (reg:GPR CA_REGNO))
1884                   (const_int -1)))
1885    (clobber (reg:GPR CA_REGNO))]
1886   ""
1887   "addme %0,%1"
1888   [(set_attr "type" "add")])
1891 (define_expand "one_cmpl<mode>2"
1892   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1893         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1894   ""
1896   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1897     {
1898       rs6000_split_logical (operands, NOT, false, false, false);
1899       DONE;
1900     }
1903 (define_insn "*one_cmpl<mode>2"
1904   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1906   ""
1907   "not %0,%1")
1909 (define_insn_and_split "*one_cmpl<mode>2_dot"
1910   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1911         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1912                     (const_int 0)))
1913    (clobber (match_scratch:GPR 0 "=r,r"))]
1914   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1915   "@
1916    not. %0,%1
1917    #"
1918   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1919   [(set (match_dup 0)
1920         (not:GPR (match_dup 1)))
1921    (set (match_dup 2)
1922         (compare:CC (match_dup 0)
1923                     (const_int 0)))]
1924   ""
1925   [(set_attr "type" "logical")
1926    (set_attr "dot" "yes")
1927    (set_attr "length" "4,8")])
1929 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1930   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1931         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1932                     (const_int 0)))
1933    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1934         (not:GPR (match_dup 1)))]
1935   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1936   "@
1937    not. %0,%1
1938    #"
1939   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1940   [(set (match_dup 0)
1941         (not:GPR (match_dup 1)))
1942    (set (match_dup 2)
1943         (compare:CC (match_dup 0)
1944                     (const_int 0)))]
1945   ""
1946   [(set_attr "type" "logical")
1947    (set_attr "dot" "yes")
1948    (set_attr "length" "4,8")])
1951 (define_expand "sub<mode>3"
1952   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1953         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1954                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1955   ""
1957   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1958     {
1959       rtx lo0 = gen_lowpart (SImode, operands[0]);
1960       rtx lo1 = gen_lowpart (SImode, operands[1]);
1961       rtx lo2 = gen_lowpart (SImode, operands[2]);
1962       rtx hi0 = gen_highpart (SImode, operands[0]);
1963       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1964       rtx hi2 = gen_highpart (SImode, operands[2]);
1966       if (!reg_or_short_operand (lo1, SImode))
1967         lo1 = force_reg (SImode, lo1);
1968       if (!adde_operand (hi1, SImode))
1969         hi1 = force_reg (SImode, hi1);
1971       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1972       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1973       DONE;
1974     }
1976   if (short_cint_operand (operands[1], <MODE>mode))
1977     {
1978       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1979       DONE;
1980     }
1983 (define_insn "*subf<mode>3"
1984   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1985         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1986                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1987   ""
1988   "subf %0,%1,%2"
1989   [(set_attr "type" "add")])
1991 (define_insn_and_split "*subf<mode>3_dot"
1992   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1993         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1994                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1995                     (const_int 0)))
1996    (clobber (match_scratch:GPR 0 "=r,r"))]
1997   "<MODE>mode == Pmode"
1998   "@
1999    subf. %0,%1,%2
2000    #"
2001   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2002   [(set (match_dup 0)
2003         (minus:GPR (match_dup 2)
2004                    (match_dup 1)))
2005    (set (match_dup 3)
2006         (compare:CC (match_dup 0)
2007                     (const_int 0)))]
2008   ""
2009   [(set_attr "type" "add")
2010    (set_attr "dot" "yes")
2011    (set_attr "length" "4,8")])
2013 (define_insn_and_split "*subf<mode>3_dot2"
2014   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2015         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2016                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2017                     (const_int 0)))
2018    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2019         (minus:GPR (match_dup 2)
2020                    (match_dup 1)))]
2021   "<MODE>mode == Pmode"
2022   "@
2023    subf. %0,%1,%2
2024    #"
2025   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2026   [(set (match_dup 0)
2027         (minus:GPR (match_dup 2)
2028                    (match_dup 1)))
2029    (set (match_dup 3)
2030         (compare:CC (match_dup 0)
2031                     (const_int 0)))]
2032   ""
2033   [(set_attr "type" "add")
2034    (set_attr "dot" "yes")
2035    (set_attr "length" "4,8")])
2037 (define_insn "subf<mode>3_imm"
2038   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2040                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2041    (clobber (reg:GPR CA_REGNO))]
2042   ""
2043   "subfic %0,%1,%2"
2044   [(set_attr "type" "add")])
2047 (define_insn "subf<mode>3_carry"
2048   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2049         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2050                  (match_operand:P 1 "gpc_reg_operand" "r")))
2051    (set (reg:P CA_REGNO)
2052         (leu:P (match_dup 1)
2053                (match_dup 2)))]
2054   ""
2055   "subf%I2c %0,%1,%2"
2056   [(set_attr "type" "add")])
2058 (define_insn "*subf<mode>3_imm_carry_0"
2059   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2060         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2061    (set (reg:P CA_REGNO)
2062         (eq:P (match_dup 1)
2063               (const_int 0)))]
2064   ""
2065   "subfic %0,%1,0"
2066   [(set_attr "type" "add")])
2068 (define_insn "*subf<mode>3_imm_carry_m1"
2069   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2070         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2071    (set (reg:P CA_REGNO)
2072         (const_int 1))]
2073   ""
2074   "subfic %0,%1,-1"
2075   [(set_attr "type" "add")])
2078 (define_expand "subf<mode>3_carry_in"
2079   [(parallel [
2080      (set (match_operand:GPR 0 "gpc_reg_operand")
2081           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2082                               (reg:GPR CA_REGNO))
2083                     (match_operand:GPR 2 "adde_operand")))
2084      (clobber (reg:GPR CA_REGNO))])]
2085   ""
2087   if (operands[2] == const0_rtx)
2088     {
2089       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2090       DONE;
2091     }
2092   if (operands[2] == constm1_rtx)
2093     {
2094       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2095       DONE;
2096     }
2099 (define_insn "*subf<mode>3_carry_in_internal"
2100   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2101         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2102                             (reg:GPR CA_REGNO))
2103                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2104    (clobber (reg:GPR CA_REGNO))]
2105   ""
2106   "subfe %0,%1,%2"
2107   [(set_attr "type" "add")])
2109 (define_insn "subf<mode>3_carry_in_0"
2110   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2111         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2112                   (reg:GPR CA_REGNO)))
2113    (clobber (reg:GPR CA_REGNO))]
2114   ""
2115   "subfze %0,%1"
2116   [(set_attr "type" "add")])
2118 (define_insn "subf<mode>3_carry_in_m1"
2119   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2120         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2121                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2122                   (const_int -2)))
2123    (clobber (reg:GPR CA_REGNO))]
2124   ""
2125   "subfme %0,%1"
2126   [(set_attr "type" "add")])
2128 (define_insn "subf<mode>3_carry_in_xx"
2129   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2130         (plus:GPR (reg:GPR CA_REGNO)
2131                   (const_int -1)))
2132    (clobber (reg:GPR CA_REGNO))]
2133   ""
2134   "subfe %0,%0,%0"
2135   [(set_attr "type" "add")])
2138 (define_insn "neg<mode>2"
2139   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2140         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2141   ""
2142   "neg %0,%1"
2143   [(set_attr "type" "add")])
2145 (define_insn_and_split "*neg<mode>2_dot"
2146   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2147         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2148                     (const_int 0)))
2149    (clobber (match_scratch:GPR 0 "=r,r"))]
2150   "<MODE>mode == Pmode"
2151   "@
2152    neg. %0,%1
2153    #"
2154   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2155   [(set (match_dup 0)
2156         (neg:GPR (match_dup 1)))
2157    (set (match_dup 2)
2158         (compare:CC (match_dup 0)
2159                     (const_int 0)))]
2160   ""
2161   [(set_attr "type" "add")
2162    (set_attr "dot" "yes")
2163    (set_attr "length" "4,8")])
2165 (define_insn_and_split "*neg<mode>2_dot2"
2166   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2167         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2168                     (const_int 0)))
2169    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2170         (neg:GPR (match_dup 1)))]
2171   "<MODE>mode == Pmode"
2172   "@
2173    neg. %0,%1
2174    #"
2175   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2176   [(set (match_dup 0)
2177         (neg:GPR (match_dup 1)))
2178    (set (match_dup 2)
2179         (compare:CC (match_dup 0)
2180                     (const_int 0)))]
2181   ""
2182   [(set_attr "type" "add")
2183    (set_attr "dot" "yes")
2184    (set_attr "length" "4,8")])
2187 (define_insn "clz<mode>2"
2188   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2190   ""
2191   "cntlz<wd> %0,%1"
2192   [(set_attr "type" "cntlz")])
2194 (define_expand "ctz<mode>2"
2195   [(set (match_dup 2)
2196         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2197    (set (match_dup 3)
2198         (and:GPR (match_dup 1)
2199                  (match_dup 2)))
2200    (set (match_dup 4)
2201         (clz:GPR (match_dup 3)))
2202    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2203                    (minus:GPR (match_dup 5)
2204                               (match_dup 4)))
2205               (clobber (reg:GPR CA_REGNO))])]
2206   ""
2208   if (TARGET_CTZ)
2209     {
2210       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2211       DONE;
2212     }
2214   operands[2] = gen_reg_rtx (<MODE>mode);
2215   operands[3] = gen_reg_rtx (<MODE>mode);
2216   operands[4] = gen_reg_rtx (<MODE>mode);
2217   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2220 (define_insn "ctz<mode>2_hw"
2221   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2222         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2223   "TARGET_CTZ"
2224   "cnttz<wd> %0,%1"
2225   [(set_attr "type" "cntlz")])
2227 (define_expand "ffs<mode>2"
2228   [(set (match_dup 2)
2229         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2230    (set (match_dup 3)
2231         (and:GPR (match_dup 1)
2232                  (match_dup 2)))
2233    (set (match_dup 4)
2234         (clz:GPR (match_dup 3)))
2235    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2236                    (minus:GPR (match_dup 5)
2237                               (match_dup 4)))
2238               (clobber (reg:GPR CA_REGNO))])]
2239   ""
2241   operands[2] = gen_reg_rtx (<MODE>mode);
2242   operands[3] = gen_reg_rtx (<MODE>mode);
2243   operands[4] = gen_reg_rtx (<MODE>mode);
2244   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2248 (define_expand "popcount<mode>2"
2249   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2250         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2251   "TARGET_POPCNTB || TARGET_POPCNTD"
2253   rs6000_emit_popcount (operands[0], operands[1]);
2254   DONE;
2257 (define_insn "popcntb<mode>2"
2258   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2259         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2260                     UNSPEC_POPCNTB))]
2261   "TARGET_POPCNTB"
2262   "popcntb %0,%1"
2263   [(set_attr "type" "popcnt")])
2265 (define_insn "popcntd<mode>2"
2266   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2267         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2268   "TARGET_POPCNTD"
2269   "popcnt<wd> %0,%1"
2270   [(set_attr "type" "popcnt")])
2273 (define_expand "parity<mode>2"
2274   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2275         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2276   "TARGET_POPCNTB"
2278   rs6000_emit_parity (operands[0], operands[1]);
2279   DONE;
2282 (define_insn "parity<mode>2_cmpb"
2283   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2284         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2285   "TARGET_CMPB && TARGET_POPCNTB"
2286   "prty<wd> %0,%1"
2287   [(set_attr "type" "popcnt")])
2290 ;; Since the hardware zeros the upper part of the register, save generating the
2291 ;; AND immediate if we are converting to unsigned
2292 (define_insn "*bswaphi2_extenddi"
2293   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2294         (zero_extend:DI
2295          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2296   "TARGET_POWERPC64"
2297   "lhbrx %0,%y1"
2298   [(set_attr "length" "4")
2299    (set_attr "type" "load")])
2301 (define_insn "*bswaphi2_extendsi"
2302   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2303         (zero_extend:SI
2304          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2305   ""
2306   "lhbrx %0,%y1"
2307   [(set_attr "length" "4")
2308    (set_attr "type" "load")])
2310 (define_expand "bswaphi2"
2311   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2312                    (bswap:HI
2313                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2314               (clobber (match_scratch:SI 2 ""))])]
2315   ""
2317   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2318     operands[1] = force_reg (HImode, operands[1]);
2321 (define_insn "bswaphi2_internal"
2322   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2323         (bswap:HI
2324          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2325    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2326   ""
2327   "@
2328    lhbrx %0,%y1
2329    sthbrx %1,%y0
2330    #"
2331   [(set_attr "length" "4,4,12")
2332    (set_attr "type" "load,store,*")])
2334 (define_split
2335   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2336         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2337    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2338   "reload_completed"
2339   [(set (match_dup 3)
2340         (and:SI (lshiftrt:SI (match_dup 4)
2341                              (const_int 8))
2342                 (const_int 255)))
2343    (set (match_dup 2)
2344         (and:SI (ashift:SI (match_dup 4)
2345                            (const_int 8))
2346                 (const_int 65280)))             ;; 0xff00
2347    (set (match_dup 3)
2348         (ior:SI (match_dup 3)
2349                 (match_dup 2)))]
2350   "
2352   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2353   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2356 (define_insn "*bswapsi2_extenddi"
2357   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2358         (zero_extend:DI
2359          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2360   "TARGET_POWERPC64"
2361   "lwbrx %0,%y1"
2362   [(set_attr "length" "4")
2363    (set_attr "type" "load")])
2365 (define_expand "bswapsi2"
2366   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2367         (bswap:SI
2368          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2369   ""
2371   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2372     operands[1] = force_reg (SImode, operands[1]);
2375 (define_insn "*bswapsi2_internal"
2376   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2377         (bswap:SI
2378          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2379   ""
2380   "@
2381    lwbrx %0,%y1
2382    stwbrx %1,%y0
2383    #"
2384   [(set_attr "length" "4,4,12")
2385    (set_attr "type" "load,store,*")])
2387 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2388 ;; zero_extract insns do not change for -mlittle.
2389 (define_split
2390   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2391         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2392   "reload_completed"
2393   [(set (match_dup 0)                                   ; DABC
2394         (rotate:SI (match_dup 1)
2395                    (const_int 24)))
2396    (set (match_dup 0)                                   ; DCBC
2397         (ior:SI (and:SI (ashift:SI (match_dup 1)
2398                                    (const_int 8))
2399                         (const_int 16711680))
2400                 (and:SI (match_dup 0)
2401                         (const_int -16711681))))
2402    (set (match_dup 0)                                   ; DCBA
2403         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2404                                      (const_int 24))
2405                         (const_int 255))
2406                 (and:SI (match_dup 0)
2407                         (const_int -256))))
2409   ]
2410   "")
2412 (define_expand "bswapdi2"
2413   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2414                    (bswap:DI
2415                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2416               (clobber (match_scratch:DI 2 ""))
2417               (clobber (match_scratch:DI 3 ""))])]
2418   ""
2420   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2421     operands[1] = force_reg (DImode, operands[1]);
2423   if (!TARGET_POWERPC64)
2424     {
2425       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2426          that uses 64-bit registers needs the same scratch registers as 64-bit
2427          mode.  */
2428       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2429       DONE;
2430     }
2433 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2434 (define_insn "*bswapdi2_ldbrx"
2435   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2436         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2437    (clobber (match_scratch:DI 2 "=X,X,&r"))
2438    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2439   "TARGET_POWERPC64 && TARGET_LDBRX
2440    && (REG_P (operands[0]) || REG_P (operands[1]))"
2441   "@
2442    ldbrx %0,%y1
2443    stdbrx %1,%y0
2444    #"
2445   [(set_attr "length" "4,4,36")
2446    (set_attr "type" "load,store,*")])
2448 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2449 (define_insn "*bswapdi2_64bit"
2450   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2451         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2452    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2453    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2454   "TARGET_POWERPC64 && !TARGET_LDBRX
2455    && (REG_P (operands[0]) || REG_P (operands[1]))
2456    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2457    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2458   "#"
2459   [(set_attr "length" "16,12,36")])
2461 (define_split
2462   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2463         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2464    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2465    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2466   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2467   [(const_int 0)]
2468   "
2470   rtx dest   = operands[0];
2471   rtx src    = operands[1];
2472   rtx op2    = operands[2];
2473   rtx op3    = operands[3];
2474   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2475                                     BYTES_BIG_ENDIAN ? 4 : 0);
2476   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2477                                      BYTES_BIG_ENDIAN ? 4 : 0);
2478   rtx addr1;
2479   rtx addr2;
2480   rtx word1;
2481   rtx word2;
2483   addr1 = XEXP (src, 0);
2484   if (GET_CODE (addr1) == PLUS)
2485     {
2486       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2487       if (TARGET_AVOID_XFORM)
2488         {
2489           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2490           addr2 = op2;
2491         }
2492       else
2493         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2494     }
2495   else if (TARGET_AVOID_XFORM)
2496     {
2497       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2498       addr2 = op2;
2499     }
2500   else
2501     {
2502       emit_move_insn (op2, GEN_INT (4));
2503       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2504     }
2506   word1 = change_address (src, SImode, addr1);
2507   word2 = change_address (src, SImode, addr2);
2509   if (BYTES_BIG_ENDIAN)
2510     {
2511       emit_insn (gen_bswapsi2 (op3_32, word2));
2512       emit_insn (gen_bswapsi2 (dest_32, word1));
2513     }
2514   else
2515     {
2516       emit_insn (gen_bswapsi2 (op3_32, word1));
2517       emit_insn (gen_bswapsi2 (dest_32, word2));
2518     }
2520   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2521   emit_insn (gen_iordi3 (dest, dest, op3));
2522   DONE;
2525 (define_split
2526   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2527         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2528    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2529    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2530   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2531   [(const_int 0)]
2532   "
2534   rtx dest   = operands[0];
2535   rtx src    = operands[1];
2536   rtx op2    = operands[2];
2537   rtx op3    = operands[3];
2538   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2539                                     BYTES_BIG_ENDIAN ? 4 : 0);
2540   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2541                                     BYTES_BIG_ENDIAN ? 4 : 0);
2542   rtx addr1;
2543   rtx addr2;
2544   rtx word1;
2545   rtx word2;
2547   addr1 = XEXP (dest, 0);
2548   if (GET_CODE (addr1) == PLUS)
2549     {
2550       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2551       if (TARGET_AVOID_XFORM)
2552         {
2553           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2554           addr2 = op2;
2555         }
2556       else
2557         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2558     }
2559   else if (TARGET_AVOID_XFORM)
2560     {
2561       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2562       addr2 = op2;
2563     }
2564   else
2565     {
2566       emit_move_insn (op2, GEN_INT (4));
2567       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2568     }
2570   word1 = change_address (dest, SImode, addr1);
2571   word2 = change_address (dest, SImode, addr2);
2573   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2575   if (BYTES_BIG_ENDIAN)
2576     {
2577       emit_insn (gen_bswapsi2 (word1, src_si));
2578       emit_insn (gen_bswapsi2 (word2, op3_si));
2579     }
2580   else
2581     {
2582       emit_insn (gen_bswapsi2 (word2, src_si));
2583       emit_insn (gen_bswapsi2 (word1, op3_si));
2584     }
2585   DONE;
2588 (define_split
2589   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2590         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2591    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2592    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2593   "TARGET_POWERPC64 && reload_completed"
2594   [(const_int 0)]
2595   "
2597   rtx dest    = operands[0];
2598   rtx src     = operands[1];
2599   rtx op2     = operands[2];
2600   rtx op3     = operands[3];
2601   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2602   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2603   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2604   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2605   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2607   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2608   emit_insn (gen_bswapsi2 (dest_si, src_si));
2609   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2610   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2611   emit_insn (gen_iordi3 (dest, dest, op3));
2612   DONE;
2615 (define_insn "bswapdi2_32bit"
2616   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2617         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2618    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2619   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2620   "#"
2621   [(set_attr "length" "16,12,36")])
2623 (define_split
2624   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2625         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2626    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2627   "!TARGET_POWERPC64 && reload_completed"
2628   [(const_int 0)]
2629   "
2631   rtx dest  = operands[0];
2632   rtx src   = operands[1];
2633   rtx op2   = operands[2];
2634   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2635   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2636   rtx addr1;
2637   rtx addr2;
2638   rtx word1;
2639   rtx word2;
2641   addr1 = XEXP (src, 0);
2642   if (GET_CODE (addr1) == PLUS)
2643     {
2644       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2645       if (TARGET_AVOID_XFORM
2646           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2647         {
2648           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2649           addr2 = op2;
2650         }
2651       else
2652         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2653     }
2654   else if (TARGET_AVOID_XFORM
2655            || REGNO (addr1) == REGNO (dest2))
2656     {
2657       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2658       addr2 = op2;
2659     }
2660   else
2661     {
2662       emit_move_insn (op2, GEN_INT (4));
2663       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2664     }
2666   word1 = change_address (src, SImode, addr1);
2667   word2 = change_address (src, SImode, addr2);
2669   emit_insn (gen_bswapsi2 (dest2, word1));
2670   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2671      thus allowing us to omit an early clobber on the output.  */
2672   emit_insn (gen_bswapsi2 (dest1, word2));
2673   DONE;
2676 (define_split
2677   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2678         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2679    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2680   "!TARGET_POWERPC64 && reload_completed"
2681   [(const_int 0)]
2682   "
2684   rtx dest = operands[0];
2685   rtx src  = operands[1];
2686   rtx op2  = operands[2];
2687   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2688   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2689   rtx addr1;
2690   rtx addr2;
2691   rtx word1;
2692   rtx word2;
2694   addr1 = XEXP (dest, 0);
2695   if (GET_CODE (addr1) == PLUS)
2696     {
2697       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2698       if (TARGET_AVOID_XFORM)
2699         {
2700           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2701           addr2 = op2;
2702         }
2703       else
2704         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2705     }
2706   else if (TARGET_AVOID_XFORM)
2707     {
2708       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2709       addr2 = op2;
2710     }
2711   else
2712     {
2713       emit_move_insn (op2, GEN_INT (4));
2714       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2715     }
2717   word1 = change_address (dest, SImode, addr1);
2718   word2 = change_address (dest, SImode, addr2);
2720   emit_insn (gen_bswapsi2 (word2, src1));
2721   emit_insn (gen_bswapsi2 (word1, src2));
2722   DONE;
2725 (define_split
2726   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2727         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2728    (clobber (match_operand:SI 2 "" ""))]
2729   "!TARGET_POWERPC64 && reload_completed"
2730   [(const_int 0)]
2731   "
2733   rtx dest  = operands[0];
2734   rtx src   = operands[1];
2735   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2736   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2737   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2738   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2740   emit_insn (gen_bswapsi2 (dest1, src2));
2741   emit_insn (gen_bswapsi2 (dest2, src1));
2742   DONE;
2746 (define_insn "mul<mode>3"
2747   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2748         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2749                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2750   ""
2751   "@
2752    mull<wd> %0,%1,%2
2753    mulli %0,%1,%2"
2754    [(set_attr "type" "mul")
2755     (set (attr "size")
2756       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2757                 (const_string "8")
2758              (match_operand:GPR 2 "short_cint_operand" "")
2759                 (const_string "16")]
2760         (const_string "<bits>")))])
2762 (define_insn_and_split "*mul<mode>3_dot"
2763   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2764         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2765                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2766                     (const_int 0)))
2767    (clobber (match_scratch:GPR 0 "=r,r"))]
2768   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2769   "@
2770    mull<wd>. %0,%1,%2
2771    #"
2772   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2773   [(set (match_dup 0)
2774         (mult:GPR (match_dup 1)
2775                   (match_dup 2)))
2776    (set (match_dup 3)
2777         (compare:CC (match_dup 0)
2778                     (const_int 0)))]
2779   ""
2780   [(set_attr "type" "mul")
2781    (set_attr "size" "<bits>")
2782    (set_attr "dot" "yes")
2783    (set_attr "length" "4,8")])
2785 (define_insn_and_split "*mul<mode>3_dot2"
2786   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2787         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2788                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2789                     (const_int 0)))
2790    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2791         (mult:GPR (match_dup 1)
2792                   (match_dup 2)))]
2793   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2794   "@
2795    mull<wd>. %0,%1,%2
2796    #"
2797   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2798   [(set (match_dup 0)
2799         (mult:GPR (match_dup 1)
2800                   (match_dup 2)))
2801    (set (match_dup 3)
2802         (compare:CC (match_dup 0)
2803                     (const_int 0)))]
2804   ""
2805   [(set_attr "type" "mul")
2806    (set_attr "size" "<bits>")
2807    (set_attr "dot" "yes")
2808    (set_attr "length" "4,8")])
2811 (define_expand "<su>mul<mode>3_highpart"
2812   [(set (match_operand:GPR 0 "gpc_reg_operand")
2813         (subreg:GPR
2814           (mult:<DMODE> (any_extend:<DMODE>
2815                           (match_operand:GPR 1 "gpc_reg_operand"))
2816                         (any_extend:<DMODE>
2817                           (match_operand:GPR 2 "gpc_reg_operand")))
2818          0))]
2819   ""
2821   if (<MODE>mode == SImode && TARGET_POWERPC64)
2822     {
2823       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2824                                              operands[2]));
2825       DONE;
2826     }
2828   if (!WORDS_BIG_ENDIAN)
2829     {
2830       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2831                                                  operands[2]));
2832       DONE;
2833     }
2836 (define_insn "*<su>mul<mode>3_highpart"
2837   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2838         (subreg:GPR
2839           (mult:<DMODE> (any_extend:<DMODE>
2840                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2841                         (any_extend:<DMODE>
2842                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2843          0))]
2844   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2845   "mulh<wd><u> %0,%1,%2"
2846   [(set_attr "type" "mul")
2847    (set_attr "size" "<bits>")])
2849 (define_insn "<su>mulsi3_highpart_le"
2850   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2851         (subreg:SI
2852           (mult:DI (any_extend:DI
2853                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2854                    (any_extend:DI
2855                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2856          4))]
2857   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2858   "mulhw<u> %0,%1,%2"
2859   [(set_attr "type" "mul")])
2861 (define_insn "<su>muldi3_highpart_le"
2862   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2863         (subreg:DI
2864           (mult:TI (any_extend:TI
2865                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2866                    (any_extend:TI
2867                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2868          8))]
2869   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2870   "mulhd<u> %0,%1,%2"
2871   [(set_attr "type" "mul")
2872    (set_attr "size" "64")])
2874 (define_insn "<su>mulsi3_highpart_64"
2875   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2876         (truncate:SI
2877           (lshiftrt:DI
2878             (mult:DI (any_extend:DI
2879                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2880                      (any_extend:DI
2881                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2882             (const_int 32))))]
2883   "TARGET_POWERPC64"
2884   "mulhw<u> %0,%1,%2"
2885   [(set_attr "type" "mul")])
2887 (define_expand "<u>mul<mode><dmode>3"
2888   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2889         (mult:<DMODE> (any_extend:<DMODE>
2890                         (match_operand:GPR 1 "gpc_reg_operand"))
2891                       (any_extend:<DMODE>
2892                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2893   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2895   rtx l = gen_reg_rtx (<MODE>mode);
2896   rtx h = gen_reg_rtx (<MODE>mode);
2897   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2898   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2899   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2900   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2901   DONE;
2904 (define_insn "*maddld4"
2905   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2906         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2907                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2908                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2909   "TARGET_MADDLD"
2910   "maddld %0,%1,%2,%3"
2911   [(set_attr "type" "mul")])
2913 (define_insn "udiv<mode>3"
2914   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2915         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2916                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2917   ""
2918   "div<wd>u %0,%1,%2"
2919   [(set_attr "type" "div")
2920    (set_attr "size" "<bits>")])
2923 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2924 ;; modulus.  If it isn't a power of two, force operands into register and do
2925 ;; a normal divide.
2926 (define_expand "div<mode>3"
2927   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2928         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2929                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2930   ""
2932   if (CONST_INT_P (operands[2])
2933       && INTVAL (operands[2]) > 0
2934       && exact_log2 (INTVAL (operands[2])) >= 0)
2935     {
2936       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2937       DONE;
2938     }
2940   operands[2] = force_reg (<MODE>mode, operands[2]);
2943 (define_insn "*div<mode>3"
2944   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2945         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2946                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2947   ""
2948   "div<wd> %0,%1,%2"
2949   [(set_attr "type" "div")
2950    (set_attr "size" "<bits>")])
2952 (define_insn "div<mode>3_sra"
2953   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2954         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2955                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2956    (clobber (reg:GPR CA_REGNO))]
2957   ""
2958   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2959   [(set_attr "type" "two")
2960    (set_attr "length" "8")])
2962 (define_insn_and_split "*div<mode>3_sra_dot"
2963   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2964         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2965                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2966                     (const_int 0)))
2967    (clobber (match_scratch:GPR 0 "=r,r"))
2968    (clobber (reg:GPR CA_REGNO))]
2969   "<MODE>mode == Pmode"
2970   "@
2971    sra<wd>i %0,%1,%p2\;addze. %0,%0
2972    #"
2973   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2974   [(parallel [(set (match_dup 0)
2975                    (div:GPR (match_dup 1)
2976                             (match_dup 2)))
2977               (clobber (reg:GPR CA_REGNO))])
2978    (set (match_dup 3)
2979         (compare:CC (match_dup 0)
2980                     (const_int 0)))]
2981   ""
2982   [(set_attr "type" "two")
2983    (set_attr "length" "8,12")
2984    (set_attr "cell_micro" "not")])
2986 (define_insn_and_split "*div<mode>3_sra_dot2"
2987   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2988         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2989                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2990                     (const_int 0)))
2991    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2992         (div:GPR (match_dup 1)
2993                  (match_dup 2)))
2994    (clobber (reg:GPR CA_REGNO))]
2995   "<MODE>mode == Pmode"
2996   "@
2997    sra<wd>i %0,%1,%p2\;addze. %0,%0
2998    #"
2999   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3000   [(parallel [(set (match_dup 0)
3001                    (div:GPR (match_dup 1)
3002                             (match_dup 2)))
3003               (clobber (reg:GPR CA_REGNO))])
3004    (set (match_dup 3)
3005         (compare:CC (match_dup 0)
3006                     (const_int 0)))]
3007   ""
3008   [(set_attr "type" "two")
3009    (set_attr "length" "8,12")
3010    (set_attr "cell_micro" "not")])
3012 (define_expand "mod<mode>3"
3013   [(set (match_operand:GPR 0 "gpc_reg_operand")
3014         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3015                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3016   ""
3018   int i;
3019   rtx temp1;
3020   rtx temp2;
3022   if (GET_CODE (operands[2]) != CONST_INT
3023       || INTVAL (operands[2]) <= 0
3024       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3025     {
3026       if (!TARGET_MODULO)
3027         FAIL;
3029       operands[2] = force_reg (<MODE>mode, operands[2]);
3030     }
3031   else
3032     {
3033       temp1 = gen_reg_rtx (<MODE>mode);
3034       temp2 = gen_reg_rtx (<MODE>mode);
3036       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3037       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3038       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3039       DONE;
3040     }
3043 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3044 ;; mod, prefer putting the result of mod into a different register
3045 (define_insn "*mod<mode>3"
3046   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3047         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3048                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3049   "TARGET_MODULO"
3050   "mods<wd> %0,%1,%2"
3051   [(set_attr "type" "div")
3052    (set_attr "size" "<bits>")])
3055 (define_insn "umod<mode>3"
3056   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3057         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3058                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3059   "TARGET_MODULO"
3060   "modu<wd> %0,%1,%2"
3061   [(set_attr "type" "div")
3062    (set_attr "size" "<bits>")])
3064 ;; On machines with modulo support, do a combined div/mod the old fashioned
3065 ;; method, since the multiply/subtract is faster than doing the mod instruction
3066 ;; after a divide.
3068 (define_peephole2
3069   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3070         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3071                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3072    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3073         (mod:GPR (match_dup 1)
3074                  (match_dup 2)))]
3075   "TARGET_MODULO
3076    && ! reg_mentioned_p (operands[0], operands[1])
3077    && ! reg_mentioned_p (operands[0], operands[2])
3078    && ! reg_mentioned_p (operands[3], operands[1])
3079    && ! reg_mentioned_p (operands[3], operands[2])"
3080   [(set (match_dup 0)
3081         (div:GPR (match_dup 1)
3082                  (match_dup 2)))
3083    (set (match_dup 3)
3084         (mult:GPR (match_dup 0)
3085                   (match_dup 2)))
3086    (set (match_dup 3)
3087         (minus:GPR (match_dup 1)
3088                    (match_dup 3)))])
3090 (define_peephole2
3091   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3092         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3093                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3094    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3095         (umod:GPR (match_dup 1)
3096                   (match_dup 2)))]
3097   "TARGET_MODULO
3098    && ! reg_mentioned_p (operands[0], operands[1])
3099    && ! reg_mentioned_p (operands[0], operands[2])
3100    && ! reg_mentioned_p (operands[3], operands[1])
3101    && ! reg_mentioned_p (operands[3], operands[2])"
3102   [(set (match_dup 0)
3103         (div:GPR (match_dup 1)
3104                  (match_dup 2)))
3105    (set (match_dup 3)
3106         (mult:GPR (match_dup 0)
3107                   (match_dup 2)))
3108    (set (match_dup 3)
3109         (minus:GPR (match_dup 1)
3110                    (match_dup 3)))])
3113 ;; Logical instructions
3114 ;; The logical instructions are mostly combined by using match_operator,
3115 ;; but the plain AND insns are somewhat different because there is no
3116 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3117 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3119 (define_expand "and<mode>3"
3120   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3121         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3122                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3123   ""
3125   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3126     {
3127       rs6000_split_logical (operands, AND, false, false, false);
3128       DONE;
3129     }
3131   if (CONST_INT_P (operands[2]))
3132     {
3133       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3134         {
3135           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3136           DONE;
3137         }
3139       if (logical_const_operand (operands[2], <MODE>mode)
3140           && rs6000_gen_cell_microcode)
3141         {
3142           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3143           DONE;
3144         }
3146       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3147         {
3148           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3149           DONE;
3150         }
3152       operands[2] = force_reg (<MODE>mode, operands[2]);
3153     }
3157 (define_insn "and<mode>3_imm"
3158   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3159         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3160                  (match_operand:GPR 2 "logical_const_operand" "n")))
3161    (clobber (match_scratch:CC 3 "=x"))]
3162   "rs6000_gen_cell_microcode
3163    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3164   "andi%e2. %0,%1,%u2"
3165   [(set_attr "type" "logical")
3166    (set_attr "dot" "yes")])
3168 (define_insn_and_split "*and<mode>3_imm_dot"
3169   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3170         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3171                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3172                     (const_int 0)))
3173    (clobber (match_scratch:GPR 0 "=r,r"))
3174    (clobber (match_scratch:CC 4 "=X,x"))]
3175   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3176    && rs6000_gen_cell_microcode
3177    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3178   "@
3179    andi%e2. %0,%1,%u2
3180    #"
3181   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3182   [(parallel [(set (match_dup 0)
3183                    (and:GPR (match_dup 1)
3184                             (match_dup 2)))
3185               (clobber (match_dup 4))])
3186    (set (match_dup 3)
3187         (compare:CC (match_dup 0)
3188                     (const_int 0)))]
3189   ""
3190   [(set_attr "type" "logical")
3191    (set_attr "dot" "yes")
3192    (set_attr "length" "4,8")])
3194 (define_insn_and_split "*and<mode>3_imm_dot2"
3195   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3196         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3197                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3198                     (const_int 0)))
3199    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3200         (and:GPR (match_dup 1)
3201                  (match_dup 2)))
3202    (clobber (match_scratch:CC 4 "=X,x"))]
3203   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3204    && rs6000_gen_cell_microcode
3205    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3206   "@
3207    andi%e2. %0,%1,%u2
3208    #"
3209   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210   [(parallel [(set (match_dup 0)
3211                    (and:GPR (match_dup 1)
3212                             (match_dup 2)))
3213               (clobber (match_dup 4))])
3214    (set (match_dup 3)
3215         (compare:CC (match_dup 0)
3216                     (const_int 0)))]
3217   ""
3218   [(set_attr "type" "logical")
3219    (set_attr "dot" "yes")
3220    (set_attr "length" "4,8")])
3222 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3223   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3224         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3225                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3226                     (const_int 0)))
3227    (clobber (match_scratch:GPR 0 "=r,r"))]
3228   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3229    && rs6000_gen_cell_microcode"
3230   "@
3231    andi%e2. %0,%1,%u2
3232    #"
3233   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3234   [(set (match_dup 0)
3235         (and:GPR (match_dup 1)
3236                  (match_dup 2)))
3237    (set (match_dup 3)
3238         (compare:CC (match_dup 0)
3239                     (const_int 0)))]
3240   ""
3241   [(set_attr "type" "logical")
3242    (set_attr "dot" "yes")
3243    (set_attr "length" "4,8")])
3245 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3246   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3247         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3248                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3249                     (const_int 0)))
3250    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3251         (and:GPR (match_dup 1)
3252                  (match_dup 2)))]
3253   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3254    && rs6000_gen_cell_microcode"
3255   "@
3256    andi%e2. %0,%1,%u2
3257    #"
3258   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3259   [(set (match_dup 0)
3260         (and:GPR (match_dup 1)
3261                  (match_dup 2)))
3262    (set (match_dup 3)
3263         (compare:CC (match_dup 0)
3264                     (const_int 0)))]
3265   ""
3266   [(set_attr "type" "logical")
3267    (set_attr "dot" "yes")
3268    (set_attr "length" "4,8")])
3270 (define_insn "*and<mode>3_imm_dot_shifted"
3271   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3272         (compare:CC
3273           (and:GPR
3274             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3275                           (match_operand:SI 4 "const_int_operand" "n"))
3276             (match_operand:GPR 2 "const_int_operand" "n"))
3277           (const_int 0)))
3278    (clobber (match_scratch:GPR 0 "=r"))]
3279   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3280                                    << INTVAL (operands[4])),
3281                           DImode)
3282    && (<MODE>mode == Pmode
3283        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3284    && rs6000_gen_cell_microcode"
3286   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3287   return "andi%e2. %0,%1,%u2";
3289   [(set_attr "type" "logical")
3290    (set_attr "dot" "yes")])
3293 (define_insn "and<mode>3_mask"
3294   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3295         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3296                  (match_operand:GPR 2 "const_int_operand" "n")))]
3297   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3299   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3301   [(set_attr "type" "shift")])
3303 (define_insn_and_split "*and<mode>3_mask_dot"
3304   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3305         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3306                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3307                     (const_int 0)))
3308    (clobber (match_scratch:GPR 0 "=r,r"))]
3309   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3310    && rs6000_gen_cell_microcode
3311    && !logical_const_operand (operands[2], <MODE>mode)
3312    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3314   if (which_alternative == 0)
3315     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3316   else
3317     return "#";
3319   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3320   [(set (match_dup 0)
3321         (and:GPR (match_dup 1)
3322                  (match_dup 2)))
3323    (set (match_dup 3)
3324         (compare:CC (match_dup 0)
3325                     (const_int 0)))]
3326   ""
3327   [(set_attr "type" "shift")
3328    (set_attr "dot" "yes")
3329    (set_attr "length" "4,8")])
3331 (define_insn_and_split "*and<mode>3_mask_dot2"
3332   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3333         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3335                     (const_int 0)))
3336    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3337         (and:GPR (match_dup 1)
3338                  (match_dup 2)))]
3339   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3340    && rs6000_gen_cell_microcode
3341    && !logical_const_operand (operands[2], <MODE>mode)
3342    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3344   if (which_alternative == 0)
3345     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3346   else
3347     return "#";
3349   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3350   [(set (match_dup 0)
3351         (and:GPR (match_dup 1)
3352                  (match_dup 2)))
3353    (set (match_dup 3)
3354         (compare:CC (match_dup 0)
3355                     (const_int 0)))]
3356   ""
3357   [(set_attr "type" "shift")
3358    (set_attr "dot" "yes")
3359    (set_attr "length" "4,8")])
3362 (define_insn_and_split "*and<mode>3_2insn"
3363   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3364         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3365                  (match_operand:GPR 2 "const_int_operand" "n")))]
3366   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3367    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3368         || (logical_const_operand (operands[2], <MODE>mode)
3369             && rs6000_gen_cell_microcode))"
3370   "#"
3371   "&& 1"
3372   [(pc)]
3374   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3375   DONE;
3377   [(set_attr "type" "shift")
3378    (set_attr "length" "8")])
3380 (define_insn_and_split "*and<mode>3_2insn_dot"
3381   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3382         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3383                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3384                     (const_int 0)))
3385    (clobber (match_scratch:GPR 0 "=r,r"))]
3386   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3387    && rs6000_gen_cell_microcode
3388    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3389    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3390         || (logical_const_operand (operands[2], <MODE>mode)
3391             && rs6000_gen_cell_microcode))"
3392   "#"
3393   "&& reload_completed"
3394   [(pc)]
3396   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3397   DONE;
3399   [(set_attr "type" "shift")
3400    (set_attr "dot" "yes")
3401    (set_attr "length" "8,12")])
3403 (define_insn_and_split "*and<mode>3_2insn_dot2"
3404   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3405         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3406                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3407                     (const_int 0)))
3408    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3409         (and:GPR (match_dup 1)
3410                  (match_dup 2)))]
3411   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3412    && rs6000_gen_cell_microcode
3413    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3414    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3415         || (logical_const_operand (operands[2], <MODE>mode)
3416             && rs6000_gen_cell_microcode))"
3417   "#"
3418   "&& reload_completed"
3419   [(pc)]
3421   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3422   DONE;
3424   [(set_attr "type" "shift")
3425    (set_attr "dot" "yes")
3426    (set_attr "length" "8,12")])
3429 (define_expand "<code><mode>3"
3430   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3431         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3432                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3433   ""
3435   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3436     {
3437       rs6000_split_logical (operands, <CODE>, false, false, false);
3438       DONE;
3439     }
3441   if (non_logical_cint_operand (operands[2], <MODE>mode))
3442     {
3443       rtx tmp = ((!can_create_pseudo_p ()
3444                   || rtx_equal_p (operands[0], operands[1]))
3445                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3447       HOST_WIDE_INT value = INTVAL (operands[2]);
3448       HOST_WIDE_INT lo = value & 0xffff;
3449       HOST_WIDE_INT hi = value - lo;
3451       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3452       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3453       DONE;
3454     }
3456   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3457     operands[2] = force_reg (<MODE>mode, operands[2]);
3460 (define_split
3461   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3462         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3463                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3464   ""
3465   [(set (match_dup 3)
3466         (iorxor:GPR (match_dup 1)
3467                     (match_dup 4)))
3468    (set (match_dup 0)
3469         (iorxor:GPR (match_dup 3)
3470                     (match_dup 5)))]
3472   operands[3] = ((!can_create_pseudo_p ()
3473                   || rtx_equal_p (operands[0], operands[1]))
3474                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3476   HOST_WIDE_INT value = INTVAL (operands[2]);
3477   HOST_WIDE_INT lo = value & 0xffff;
3478   HOST_WIDE_INT hi = value - lo;
3480   operands[4] = GEN_INT (hi);
3481   operands[5] = GEN_INT (lo);
3484 (define_insn "*bool<mode>3_imm"
3485   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3486         (match_operator:GPR 3 "boolean_or_operator"
3487          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3488           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3489   ""
3490   "%q3i%e2 %0,%1,%u2"
3491   [(set_attr "type" "logical")])
3493 (define_insn "*bool<mode>3"
3494   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3495         (match_operator:GPR 3 "boolean_operator"
3496          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3497           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3498   ""
3499   "%q3 %0,%1,%2"
3500   [(set_attr "type" "logical")])
3502 (define_insn_and_split "*bool<mode>3_dot"
3503   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3504         (compare:CC (match_operator:GPR 3 "boolean_operator"
3505          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3506           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3507          (const_int 0)))
3508    (clobber (match_scratch:GPR 0 "=r,r"))]
3509   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3510   "@
3511    %q3. %0,%1,%2
3512    #"
3513   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3514   [(set (match_dup 0)
3515         (match_dup 3))
3516    (set (match_dup 4)
3517         (compare:CC (match_dup 0)
3518                     (const_int 0)))]
3519   ""
3520   [(set_attr "type" "logical")
3521    (set_attr "dot" "yes")
3522    (set_attr "length" "4,8")])
3524 (define_insn_and_split "*bool<mode>3_dot2"
3525   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3526         (compare:CC (match_operator:GPR 3 "boolean_operator"
3527          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3528           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3529          (const_int 0)))
3530    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3531         (match_dup 3))]
3532   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3533   "@
3534    %q3. %0,%1,%2
3535    #"
3536   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3537   [(set (match_dup 0)
3538         (match_dup 3))
3539    (set (match_dup 4)
3540         (compare:CC (match_dup 0)
3541                     (const_int 0)))]
3542   ""
3543   [(set_attr "type" "logical")
3544    (set_attr "dot" "yes")
3545    (set_attr "length" "4,8")])
3548 (define_insn "*boolc<mode>3"
3549   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3550         (match_operator:GPR 3 "boolean_operator"
3551          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3552           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3553   ""
3554   "%q3 %0,%1,%2"
3555   [(set_attr "type" "logical")])
3557 (define_insn_and_split "*boolc<mode>3_dot"
3558   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3559         (compare:CC (match_operator:GPR 3 "boolean_operator"
3560          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3561           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3562          (const_int 0)))
3563    (clobber (match_scratch:GPR 0 "=r,r"))]
3564   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3565   "@
3566    %q3. %0,%1,%2
3567    #"
3568   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3569   [(set (match_dup 0)
3570         (match_dup 3))
3571    (set (match_dup 4)
3572         (compare:CC (match_dup 0)
3573                     (const_int 0)))]
3574   ""
3575   [(set_attr "type" "logical")
3576    (set_attr "dot" "yes")
3577    (set_attr "length" "4,8")])
3579 (define_insn_and_split "*boolc<mode>3_dot2"
3580   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3581         (compare:CC (match_operator:GPR 3 "boolean_operator"
3582          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3583           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3584          (const_int 0)))
3585    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3586         (match_dup 3))]
3587   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3588   "@
3589    %q3. %0,%1,%2
3590    #"
3591   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3592   [(set (match_dup 0)
3593         (match_dup 3))
3594    (set (match_dup 4)
3595         (compare:CC (match_dup 0)
3596                     (const_int 0)))]
3597   ""
3598   [(set_attr "type" "logical")
3599    (set_attr "dot" "yes")
3600    (set_attr "length" "4,8")])
3603 (define_insn "*boolcc<mode>3"
3604   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3605         (match_operator:GPR 3 "boolean_operator"
3606          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3607           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3608   ""
3609   "%q3 %0,%1,%2"
3610   [(set_attr "type" "logical")])
3612 (define_insn_and_split "*boolcc<mode>3_dot"
3613   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3614         (compare:CC (match_operator:GPR 3 "boolean_operator"
3615          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3616           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3617          (const_int 0)))
3618    (clobber (match_scratch:GPR 0 "=r,r"))]
3619   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3620   "@
3621    %q3. %0,%1,%2
3622    #"
3623   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3624   [(set (match_dup 0)
3625         (match_dup 3))
3626    (set (match_dup 4)
3627         (compare:CC (match_dup 0)
3628                     (const_int 0)))]
3629   ""
3630   [(set_attr "type" "logical")
3631    (set_attr "dot" "yes")
3632    (set_attr "length" "4,8")])
3634 (define_insn_and_split "*boolcc<mode>3_dot2"
3635   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3636         (compare:CC (match_operator:GPR 3 "boolean_operator"
3637          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3638           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3639          (const_int 0)))
3640    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3641         (match_dup 3))]
3642   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3643   "@
3644    %q3. %0,%1,%2
3645    #"
3646   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3647   [(set (match_dup 0)
3648         (match_dup 3))
3649    (set (match_dup 4)
3650         (compare:CC (match_dup 0)
3651                     (const_int 0)))]
3652   ""
3653   [(set_attr "type" "logical")
3654    (set_attr "dot" "yes")
3655    (set_attr "length" "4,8")])
3658 ;; TODO: Should have dots of this as well.
3659 (define_insn "*eqv<mode>3"
3660   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3661         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3662                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3663   ""
3664   "eqv %0,%1,%2"
3665   [(set_attr "type" "logical")])
3667 ;; Rotate-and-mask and insert.
3669 (define_insn "*rotl<mode>3_mask"
3670   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3671         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3672                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3673                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3674                  (match_operand:GPR 3 "const_int_operand" "n")))]
3675   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3677   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3679   [(set_attr "type" "shift")
3680    (set_attr "maybe_var_shift" "yes")])
3682 (define_insn_and_split "*rotl<mode>3_mask_dot"
3683   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3684         (compare:CC
3685           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3686                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3687                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3688                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3689           (const_int 0)))
3690    (clobber (match_scratch:GPR 0 "=r,r"))]
3691   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3692    && rs6000_gen_cell_microcode
3693    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3695   if (which_alternative == 0)
3696     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3697   else
3698     return "#";
3700   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3701   [(set (match_dup 0)
3702         (and:GPR (match_dup 4)
3703                  (match_dup 3)))
3704    (set (match_dup 5)
3705         (compare:CC (match_dup 0)
3706                     (const_int 0)))]
3707   ""
3708   [(set_attr "type" "shift")
3709    (set_attr "maybe_var_shift" "yes")
3710    (set_attr "dot" "yes")
3711    (set_attr "length" "4,8")])
3713 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3714   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3715         (compare:CC
3716           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3717                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3718                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3719                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3720           (const_int 0)))
3721    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3722         (and:GPR (match_dup 4)
3723                  (match_dup 3)))]
3724   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3725    && rs6000_gen_cell_microcode
3726    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3728   if (which_alternative == 0)
3729     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3730   else
3731     return "#";
3733   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3734   [(set (match_dup 0)
3735         (and:GPR (match_dup 4)
3736                  (match_dup 3)))
3737    (set (match_dup 5)
3738         (compare:CC (match_dup 0)
3739                     (const_int 0)))]
3740   ""
3741   [(set_attr "type" "shift")
3742    (set_attr "maybe_var_shift" "yes")
3743    (set_attr "dot" "yes")
3744    (set_attr "length" "4,8")])
3746 ; Special case for less-than-0.  We can do it with just one machine
3747 ; instruction, but the generic optimizers do not realise it is cheap.
3748 (define_insn "*lt0_disi"
3749   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3750         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3751                (const_int 0)))]
3752   "TARGET_POWERPC64"
3753   "rlwinm %0,%1,1,31,31"
3754   [(set_attr "type" "shift")])
3758 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3759 ; both are an AND so are the same precedence).
3760 (define_insn "*rotl<mode>3_insert"
3761   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3763                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3764                             (match_operand:SI 2 "const_int_operand" "n")])
3765                           (match_operand:GPR 3 "const_int_operand" "n"))
3766                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3767                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3768   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3769    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3771   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3773   [(set_attr "type" "insert")])
3774 ; FIXME: this needs an attr "size", so that the scheduler can see the
3775 ; difference between rlwimi and rldimi.  We also might want dot forms,
3776 ; but not for rlwimi on POWER4 and similar processors.
3778 (define_insn "*rotl<mode>3_insert_2"
3779   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3780         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3781                           (match_operand:GPR 6 "const_int_operand" "n"))
3782                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3783                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3784                             (match_operand:SI 2 "const_int_operand" "n")])
3785                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3786   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3787    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3789   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3791   [(set_attr "type" "insert")])
3793 ; There are also some forms without one of the ANDs.
3794 (define_insn "*rotl<mode>3_insert_3"
3795   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3796         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3797                           (match_operand:GPR 4 "const_int_operand" "n"))
3798                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3799                              (match_operand:SI 2 "const_int_operand" "n"))))]
3800   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3802   if (<MODE>mode == SImode)
3803     return "rlwimi %0,%1,%h2,0,31-%h2";
3804   else
3805     return "rldimi %0,%1,%H2,0";
3807   [(set_attr "type" "insert")])
3809 (define_insn "*rotl<mode>3_insert_4"
3810   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3811         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3812                           (match_operand:GPR 4 "const_int_operand" "n"))
3813                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3814                                (match_operand:SI 2 "const_int_operand" "n"))))]
3815   "<MODE>mode == SImode &&
3816    GET_MODE_PRECISION (<MODE>mode)
3817    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3819   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3820                          - INTVAL (operands[2]));
3821   if (<MODE>mode == SImode)
3822     return "rlwimi %0,%1,%h2,32-%h2,31";
3823   else
3824     return "rldimi %0,%1,%H2,64-%H2";
3826   [(set_attr "type" "insert")])
3829 ; This handles the important case of multiple-precision shifts.  There is
3830 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3831 (define_split
3832   [(set (match_operand:GPR 0 "gpc_reg_operand")
3833         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3834                              (match_operand:SI 3 "const_int_operand"))
3835                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3836                                (match_operand:SI 4 "const_int_operand"))))]
3837   "can_create_pseudo_p ()
3838    && INTVAL (operands[3]) + INTVAL (operands[4])
3839       >= GET_MODE_PRECISION (<MODE>mode)"
3840   [(set (match_dup 5)
3841         (lshiftrt:GPR (match_dup 2)
3842                       (match_dup 4)))
3843    (set (match_dup 0)
3844         (ior:GPR (and:GPR (match_dup 5)
3845                           (match_dup 6))
3846                  (ashift:GPR (match_dup 1)
3847                              (match_dup 3))))]
3849   unsigned HOST_WIDE_INT mask = 1;
3850   mask = (mask << INTVAL (operands[3])) - 1;
3851   operands[5] = gen_reg_rtx (<MODE>mode);
3852   operands[6] = GEN_INT (mask);
3855 (define_split
3856   [(set (match_operand:GPR 0 "gpc_reg_operand")
3857         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3858                                (match_operand:SI 4 "const_int_operand"))
3859                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3860                              (match_operand:SI 3 "const_int_operand"))))]
3861   "can_create_pseudo_p ()
3862    && INTVAL (operands[3]) + INTVAL (operands[4])
3863       >= GET_MODE_PRECISION (<MODE>mode)"
3864   [(set (match_dup 5)
3865         (lshiftrt:GPR (match_dup 2)
3866                       (match_dup 4)))
3867    (set (match_dup 0)
3868         (ior:GPR (and:GPR (match_dup 5)
3869                           (match_dup 6))
3870                  (ashift:GPR (match_dup 1)
3871                              (match_dup 3))))]
3873   unsigned HOST_WIDE_INT mask = 1;
3874   mask = (mask << INTVAL (operands[3])) - 1;
3875   operands[5] = gen_reg_rtx (<MODE>mode);
3876   operands[6] = GEN_INT (mask);
3880 ; Another important case is setting some bits to 1; we can do that with
3881 ; an insert instruction, in many cases.
3882 (define_insn_and_split "*ior<mode>_mask"
3883   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3884         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3885                  (match_operand:GPR 2 "const_int_operand" "n")))
3886    (clobber (match_scratch:GPR 3 "=r"))]
3887   "!logical_const_operand (operands[2], <MODE>mode)
3888    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3889   "#"
3890   "&& 1"
3891   [(set (match_dup 3)
3892         (const_int -1))
3893    (set (match_dup 0)
3894         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3895                                       (match_dup 4))
3896                           (match_dup 2))
3897                  (and:GPR (match_dup 1)
3898                           (match_dup 5))))]
3900   int nb, ne;
3901   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3902   if (GET_CODE (operands[3]) == SCRATCH)
3903     operands[3] = gen_reg_rtx (<MODE>mode);
3904   operands[4] = GEN_INT (ne);
3905   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3907   [(set_attr "type" "two")
3908    (set_attr "length" "8")])
3911 ;; Now the simple shifts.
3913 (define_insn "rotl<mode>3"
3914   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3915         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3916                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3917   ""
3918   "rotl<wd>%I2 %0,%1,%<hH>2"
3919   [(set_attr "type" "shift")
3920    (set_attr "maybe_var_shift" "yes")])
3922 (define_insn "*rotlsi3_64"
3923   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3924         (zero_extend:DI
3925             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3926                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3927   "TARGET_POWERPC64"
3928   "rotlw%I2 %0,%1,%h2"
3929   [(set_attr "type" "shift")
3930    (set_attr "maybe_var_shift" "yes")])
3932 (define_insn_and_split "*rotl<mode>3_dot"
3933   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3934         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3935                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3936                     (const_int 0)))
3937    (clobber (match_scratch:GPR 0 "=r,r"))]
3938   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3939   "@
3940    rotl<wd>%I2. %0,%1,%<hH>2
3941    #"
3942   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3943   [(set (match_dup 0)
3944         (rotate:GPR (match_dup 1)
3945                     (match_dup 2)))
3946    (set (match_dup 3)
3947         (compare:CC (match_dup 0)
3948                     (const_int 0)))]
3949   ""
3950   [(set_attr "type" "shift")
3951    (set_attr "maybe_var_shift" "yes")
3952    (set_attr "dot" "yes")
3953    (set_attr "length" "4,8")])
3955 (define_insn_and_split "*rotl<mode>3_dot2"
3956   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3957         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3958                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3959                     (const_int 0)))
3960    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3961         (rotate:GPR (match_dup 1)
3962                     (match_dup 2)))]
3963   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3964   "@
3965    rotl<wd>%I2. %0,%1,%<hH>2
3966    #"
3967   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3968   [(set (match_dup 0)
3969         (rotate:GPR (match_dup 1)
3970                     (match_dup 2)))
3971    (set (match_dup 3)
3972         (compare:CC (match_dup 0)
3973                     (const_int 0)))]
3974   ""
3975   [(set_attr "type" "shift")
3976    (set_attr "maybe_var_shift" "yes")
3977    (set_attr "dot" "yes")
3978    (set_attr "length" "4,8")])
3981 (define_insn "ashl<mode>3"
3982   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3983         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3984                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3985   ""
3986   "sl<wd>%I2 %0,%1,%<hH>2"
3987   [(set_attr "type" "shift")
3988    (set_attr "maybe_var_shift" "yes")])
3990 (define_insn "*ashlsi3_64"
3991   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3992         (zero_extend:DI
3993             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3994                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3995   "TARGET_POWERPC64"
3996   "slw%I2 %0,%1,%h2"
3997   [(set_attr "type" "shift")
3998    (set_attr "maybe_var_shift" "yes")])
4000 (define_insn_and_split "*ashl<mode>3_dot"
4001   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4002         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4003                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4004                     (const_int 0)))
4005    (clobber (match_scratch:GPR 0 "=r,r"))]
4006   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4007   "@
4008    sl<wd>%I2. %0,%1,%<hH>2
4009    #"
4010   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4011   [(set (match_dup 0)
4012         (ashift:GPR (match_dup 1)
4013                     (match_dup 2)))
4014    (set (match_dup 3)
4015         (compare:CC (match_dup 0)
4016                     (const_int 0)))]
4017   ""
4018   [(set_attr "type" "shift")
4019    (set_attr "maybe_var_shift" "yes")
4020    (set_attr "dot" "yes")
4021    (set_attr "length" "4,8")])
4023 (define_insn_and_split "*ashl<mode>3_dot2"
4024   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4025         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4026                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4027                     (const_int 0)))
4028    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4029         (ashift:GPR (match_dup 1)
4030                     (match_dup 2)))]
4031   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4032   "@
4033    sl<wd>%I2. %0,%1,%<hH>2
4034    #"
4035   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4036   [(set (match_dup 0)
4037         (ashift:GPR (match_dup 1)
4038                     (match_dup 2)))
4039    (set (match_dup 3)
4040         (compare:CC (match_dup 0)
4041                     (const_int 0)))]
4042   ""
4043   [(set_attr "type" "shift")
4044    (set_attr "maybe_var_shift" "yes")
4045    (set_attr "dot" "yes")
4046    (set_attr "length" "4,8")])
4048 ;; Pretend we have a memory form of extswsli until register allocation is done
4049 ;; so that we use LWZ to load the value from memory, instead of LWA.
4050 (define_insn_and_split "ashdi3_extswsli"
4051   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4052         (ashift:DI
4053          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4054          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4055   "TARGET_EXTSWSLI"
4056   "@
4057    extswsli %0,%1,%2
4058    #"
4059   "&& reload_completed && MEM_P (operands[1])"
4060   [(set (match_dup 3)
4061         (match_dup 1))
4062    (set (match_dup 0)
4063         (ashift:DI (sign_extend:DI (match_dup 3))
4064                    (match_dup 2)))]
4066   operands[3] = gen_lowpart (SImode, operands[0]);
4068   [(set_attr "type" "shift")
4069    (set_attr "maybe_var_shift" "no")])
4072 (define_insn_and_split "ashdi3_extswsli_dot"
4073   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4074         (compare:CC
4075          (ashift:DI
4076           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4077           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4078          (const_int 0)))
4079    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4080   "TARGET_EXTSWSLI"
4081   "@
4082    extswsli. %0,%1,%2
4083    #
4084    #
4085    #"
4086   "&& reload_completed
4087    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4088        || memory_operand (operands[1], SImode))"
4089   [(pc)]
4091   rtx dest = operands[0];
4092   rtx src = operands[1];
4093   rtx shift = operands[2];
4094   rtx cr = operands[3];
4095   rtx src2;
4097   if (!MEM_P (src))
4098     src2 = src;
4099   else
4100     {
4101       src2 = gen_lowpart (SImode, dest);
4102       emit_move_insn (src2, src);
4103     }
4105   if (REGNO (cr) == CR0_REGNO)
4106     {
4107       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4108       DONE;
4109     }
4111   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4112   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4113   DONE;
4115   [(set_attr "type" "shift")
4116    (set_attr "maybe_var_shift" "no")
4117    (set_attr "dot" "yes")
4118    (set_attr "length" "4,8,8,12")])
4120 (define_insn_and_split "ashdi3_extswsli_dot2"
4121   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4122         (compare:CC
4123          (ashift:DI
4124           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4125           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4126          (const_int 0)))
4127    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4128         (ashift:DI (sign_extend:DI (match_dup 1))
4129                    (match_dup 2)))]
4130   "TARGET_EXTSWSLI"
4131   "@
4132    extswsli. %0,%1,%2
4133    #
4134    #
4135    #"
4136   "&& reload_completed
4137    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4138        || memory_operand (operands[1], SImode))"
4139   [(pc)]
4141   rtx dest = operands[0];
4142   rtx src = operands[1];
4143   rtx shift = operands[2];
4144   rtx cr = operands[3];
4145   rtx src2;
4147   if (!MEM_P (src))
4148     src2 = src;
4149   else
4150     {
4151       src2 = gen_lowpart (SImode, dest);
4152       emit_move_insn (src2, src);
4153     }
4155   if (REGNO (cr) == CR0_REGNO)
4156     {
4157       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4158       DONE;
4159     }
4161   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4162   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4163   DONE;
4165   [(set_attr "type" "shift")
4166    (set_attr "maybe_var_shift" "no")
4167    (set_attr "dot" "yes")
4168    (set_attr "length" "4,8,8,12")])
4170 (define_insn "lshr<mode>3"
4171   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4172         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4173                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4174   ""
4175   "sr<wd>%I2 %0,%1,%<hH>2"
4176   [(set_attr "type" "shift")
4177    (set_attr "maybe_var_shift" "yes")])
4179 (define_insn "*lshrsi3_64"
4180   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4181         (zero_extend:DI
4182             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4183                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4184   "TARGET_POWERPC64"
4185   "srw%I2 %0,%1,%h2"
4186   [(set_attr "type" "shift")
4187    (set_attr "maybe_var_shift" "yes")])
4189 (define_insn_and_split "*lshr<mode>3_dot"
4190   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4191         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4192                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4193                     (const_int 0)))
4194    (clobber (match_scratch:GPR 0 "=r,r"))]
4195   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4196   "@
4197    sr<wd>%I2. %0,%1,%<hH>2
4198    #"
4199   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4200   [(set (match_dup 0)
4201         (lshiftrt:GPR (match_dup 1)
4202                       (match_dup 2)))
4203    (set (match_dup 3)
4204         (compare:CC (match_dup 0)
4205                     (const_int 0)))]
4206   ""
4207   [(set_attr "type" "shift")
4208    (set_attr "maybe_var_shift" "yes")
4209    (set_attr "dot" "yes")
4210    (set_attr "length" "4,8")])
4212 (define_insn_and_split "*lshr<mode>3_dot2"
4213   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4214         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4215                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4216                     (const_int 0)))
4217    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4218         (lshiftrt:GPR (match_dup 1)
4219                       (match_dup 2)))]
4220   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4221   "@
4222    sr<wd>%I2. %0,%1,%<hH>2
4223    #"
4224   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4225   [(set (match_dup 0)
4226         (lshiftrt:GPR (match_dup 1)
4227                       (match_dup 2)))
4228    (set (match_dup 3)
4229         (compare:CC (match_dup 0)
4230                     (const_int 0)))]
4231   ""
4232   [(set_attr "type" "shift")
4233    (set_attr "maybe_var_shift" "yes")
4234    (set_attr "dot" "yes")
4235    (set_attr "length" "4,8")])
4238 (define_insn "ashr<mode>3"
4239   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4240         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4241                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4242    (clobber (reg:GPR CA_REGNO))]
4243   ""
4244   "sra<wd>%I2 %0,%1,%<hH>2"
4245   [(set_attr "type" "shift")
4246    (set_attr "maybe_var_shift" "yes")])
4248 (define_insn "*ashrsi3_64"
4249   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4250         (sign_extend:DI
4251             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4252                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4253    (clobber (reg:SI CA_REGNO))]
4254   "TARGET_POWERPC64"
4255   "sraw%I2 %0,%1,%h2"
4256   [(set_attr "type" "shift")
4257    (set_attr "maybe_var_shift" "yes")])
4259 (define_insn_and_split "*ashr<mode>3_dot"
4260   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4261         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4262                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4263                     (const_int 0)))
4264    (clobber (match_scratch:GPR 0 "=r,r"))
4265    (clobber (reg:GPR CA_REGNO))]
4266   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4267   "@
4268    sra<wd>%I2. %0,%1,%<hH>2
4269    #"
4270   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4271   [(parallel [(set (match_dup 0)
4272                    (ashiftrt:GPR (match_dup 1)
4273                                  (match_dup 2)))
4274               (clobber (reg:GPR CA_REGNO))])
4275    (set (match_dup 3)
4276         (compare:CC (match_dup 0)
4277                     (const_int 0)))]
4278   ""
4279   [(set_attr "type" "shift")
4280    (set_attr "maybe_var_shift" "yes")
4281    (set_attr "dot" "yes")
4282    (set_attr "length" "4,8")])
4284 (define_insn_and_split "*ashr<mode>3_dot2"
4285   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4286         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4287                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4288                     (const_int 0)))
4289    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4290         (ashiftrt:GPR (match_dup 1)
4291                       (match_dup 2)))
4292    (clobber (reg:GPR CA_REGNO))]
4293   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4294   "@
4295    sra<wd>%I2. %0,%1,%<hH>2
4296    #"
4297   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4298   [(parallel [(set (match_dup 0)
4299                    (ashiftrt:GPR (match_dup 1)
4300                                  (match_dup 2)))
4301               (clobber (reg:GPR CA_REGNO))])
4302    (set (match_dup 3)
4303         (compare:CC (match_dup 0)
4304                     (const_int 0)))]
4305   ""
4306   [(set_attr "type" "shift")
4307    (set_attr "maybe_var_shift" "yes")
4308    (set_attr "dot" "yes")
4309    (set_attr "length" "4,8")])
4311 ;; Builtins to replace a division to generate FRE reciprocal estimate
4312 ;; instructions and the necessary fixup instructions
4313 (define_expand "recip<mode>3"
4314   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4315    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4316    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4317   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4319    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4320    DONE;
4323 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4324 ;; hardware division.  This is only done before register allocation and with
4325 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4326 (define_split
4327   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4328         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4329                     (match_operand 2 "gpc_reg_operand" "")))]
4330   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4331    && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4332    && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4333   [(const_int 0)]
4335   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4336   DONE;
4339 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4340 ;; appropriate fixup.
4341 (define_expand "rsqrt<mode>2"
4342   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4343    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4344   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4346   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4347   DONE;
4350 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4351 ;; modes here, and also add in conditional vsx/power8-vector support to access
4352 ;; values in the traditional Altivec registers if the appropriate
4353 ;; -mupper-regs-{df,sf} option is enabled.
4355 (define_expand "abs<mode>2"
4356   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4357         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4358   "TARGET_<MODE>_INSN"
4359   "")
4361 (define_insn "*abs<mode>2_fpr"
4362   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4363         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4364   "TARGET_<MODE>_FPR"
4365   "@
4366    fabs %0,%1
4367    xsabsdp %x0,%x1"
4368   [(set_attr "type" "fpsimple")
4369    (set_attr "fp_type" "fp_addsub_<Fs>")])
4371 (define_insn "*nabs<mode>2_fpr"
4372   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4373         (neg:SFDF
4374          (abs:SFDF
4375           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4376   "TARGET_<MODE>_FPR"
4377   "@
4378    fnabs %0,%1
4379    xsnabsdp %x0,%x1"
4380   [(set_attr "type" "fpsimple")
4381    (set_attr "fp_type" "fp_addsub_<Fs>")])
4383 (define_expand "neg<mode>2"
4384   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4385         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4386   "TARGET_<MODE>_INSN"
4387   "")
4389 (define_insn "*neg<mode>2_fpr"
4390   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4391         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4392   "TARGET_<MODE>_FPR"
4393   "@
4394    fneg %0,%1
4395    xsnegdp %x0,%x1"
4396   [(set_attr "type" "fpsimple")
4397    (set_attr "fp_type" "fp_addsub_<Fs>")])
4399 (define_expand "add<mode>3"
4400   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4401         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4402                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4403   "TARGET_<MODE>_INSN"
4404   "")
4406 (define_insn "*add<mode>3_fpr"
4407   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4408         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4409                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4410   "TARGET_<MODE>_FPR"
4411   "@
4412    fadd<Ftrad> %0,%1,%2
4413    xsadd<Fvsx> %x0,%x1,%x2"
4414   [(set_attr "type" "fp")
4415    (set_attr "fp_type" "fp_addsub_<Fs>")])
4417 (define_expand "sub<mode>3"
4418   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4419         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4420                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4421   "TARGET_<MODE>_INSN"
4422   "")
4424 (define_insn "*sub<mode>3_fpr"
4425   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4426         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4427                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4428   "TARGET_<MODE>_FPR"
4429   "@
4430    fsub<Ftrad> %0,%1,%2
4431    xssub<Fvsx> %x0,%x1,%x2"
4432   [(set_attr "type" "fp")
4433    (set_attr "fp_type" "fp_addsub_<Fs>")])
4435 (define_expand "mul<mode>3"
4436   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4437         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4438                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4439   "TARGET_<MODE>_INSN"
4440   "")
4442 (define_insn "*mul<mode>3_fpr"
4443   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4444         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4445                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4446   "TARGET_<MODE>_FPR"
4447   "@
4448    fmul<Ftrad> %0,%1,%2
4449    xsmul<Fvsx> %x0,%x1,%x2"
4450   [(set_attr "type" "dmul")
4451    (set_attr "fp_type" "fp_mul_<Fs>")])
4453 (define_expand "div<mode>3"
4454   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4455         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4456                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4457   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4458   "")
4460 (define_insn "*div<mode>3_fpr"
4461   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4462         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4463                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4464   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4465   "@
4466    fdiv<Ftrad> %0,%1,%2
4467    xsdiv<Fvsx> %x0,%x1,%x2"
4468   [(set_attr "type" "<Fs>div")
4469    (set_attr "fp_type" "fp_div_<Fs>")])
4471 (define_insn "*sqrt<mode>2_internal"
4472   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4473         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4474   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4475    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4476   "@
4477    fsqrt<Ftrad> %0,%1
4478    xssqrt<Fvsx> %x0,%x1"
4479   [(set_attr "type" "<Fs>sqrt")
4480    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4482 (define_expand "sqrt<mode>2"
4483   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4484         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4485   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4486    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4488   if (<MODE>mode == SFmode
4489       && TARGET_RECIP_PRECISION
4490       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4491       && !optimize_function_for_size_p (cfun)
4492       && flag_finite_math_only && !flag_trapping_math
4493       && flag_unsafe_math_optimizations)
4494     {
4495       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4496       DONE;
4497     }
4500 ;; Floating point reciprocal approximation
4501 (define_insn "fre<Fs>"
4502   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4503         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4504                      UNSPEC_FRES))]
4505   "TARGET_<FFRE>"
4506   "@
4507    fre<Ftrad> %0,%1
4508    xsre<Fvsx> %x0,%x1"
4509   [(set_attr "type" "fp")])
4511 (define_insn "*rsqrt<mode>2"
4512   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4513         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4514                      UNSPEC_RSQRT))]
4515   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4516   "@
4517    frsqrte<Ftrad> %0,%1
4518    xsrsqrte<Fvsx> %x0,%x1"
4519   [(set_attr "type" "fp")])
4521 ;; Floating point comparisons
4522 (define_insn "*cmp<mode>_fpr"
4523   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4524         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4525                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4526   "TARGET_<MODE>_FPR"
4527   "@
4528    fcmpu %0,%1,%2
4529    xscmpudp %0,%x1,%x2"
4530   [(set_attr "type" "fpcompare")])
4532 ;; Floating point conversions
4533 (define_expand "extendsfdf2"
4534   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4535         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4536   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4537   "")
4539 (define_insn_and_split "*extendsfdf2_fpr"
4540   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4541         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4542   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4543   "@
4544    #
4545    fmr %0,%1
4546    lfs%U1%X1 %0,%1
4547    #
4548    xscpsgndp %x0,%x1,%x1
4549    lxsspx %x0,%y1
4550    lxssp %0,%1"
4551   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4552   [(const_int 0)]
4554   emit_note (NOTE_INSN_DELETED);
4555   DONE;
4557   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4559 (define_expand "truncdfsf2"
4560   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4561         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4562   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4563   "")
4565 (define_insn "*truncdfsf2_fpr"
4566   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4567         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4568   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4569   "@
4570    frsp %0,%1
4571    xsrsp %x0,%x1"
4572   [(set_attr "type" "fp")])
4574 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4575 ;; builtins.c and optabs.c that are not correct for IBM long double
4576 ;; when little-endian.
4577 (define_expand "signbit<mode>2"
4578   [(set (match_dup 2)
4579         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4580    (set (match_dup 3)
4581         (subreg:DI (match_dup 2) 0))
4582    (set (match_dup 4)
4583         (match_dup 5))
4584    (set (match_operand:SI 0 "gpc_reg_operand" "")
4585         (match_dup 6))]
4586   "TARGET_HARD_FLOAT
4587    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4588    && (!FLOAT128_IEEE_P (<MODE>mode)
4589        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4591   if (FLOAT128_IEEE_P (<MODE>mode))
4592     {
4593       if (<MODE>mode == KFmode)
4594         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4595       else if (<MODE>mode == TFmode)
4596         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4597       else
4598         gcc_unreachable ();
4599       DONE;
4600     }
4601   operands[2] = gen_reg_rtx (DFmode);
4602   operands[3] = gen_reg_rtx (DImode);
4603   if (TARGET_POWERPC64)
4604     {
4605       operands[4] = gen_reg_rtx (DImode);
4606       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4607       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4608                                     WORDS_BIG_ENDIAN ? 4 : 0);
4609     }
4610   else
4611     {
4612       operands[4] = gen_reg_rtx (SImode);
4613       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4614                                     WORDS_BIG_ENDIAN ? 0 : 4);
4615       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4616     }
4619 (define_expand "copysign<mode>3"
4620   [(set (match_dup 3)
4621         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4622    (set (match_dup 4)
4623         (neg:SFDF (abs:SFDF (match_dup 1))))
4624    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4625         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4626                                (match_dup 5))
4627                          (match_dup 3)
4628                          (match_dup 4)))]
4629   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4630    && ((TARGET_PPC_GFXOPT
4631         && !HONOR_NANS (<MODE>mode)
4632         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4633        || TARGET_CMPB
4634        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4636   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4637     {
4638       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4639                                              operands[2]));
4640       DONE;
4641     }
4643    operands[3] = gen_reg_rtx (<MODE>mode);
4644    operands[4] = gen_reg_rtx (<MODE>mode);
4645    operands[5] = CONST0_RTX (<MODE>mode);
4646   })
4648 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4649 ;; and load.
4650 (define_insn_and_split "signbit<mode>2_dm"
4651   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4652         (unspec:SI
4653          [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4654          UNSPEC_SIGNBIT))]
4655   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4656   "#"
4657   "&& reload_completed"
4658   [(const_int 0)]
4660   rs6000_split_signbit (operands[0], operands[1]);
4661   DONE;
4663  [(set_attr "length" "8,8,12")
4664   (set_attr "type" "mftgpr,load,integer")])
4666 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4667 ;; point types, which makes normal SUBREG's problematical. Instead use a
4668 ;; special pattern to avoid using a normal movdi.
4669 (define_insn "signbit<mode>2_dm2"
4670   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4671         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4672                     (const_int 0)]
4673                    UNSPEC_SIGNBIT))]
4674   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4675   "mfvsrd %0,%x1"
4676  [(set_attr "type" "mftgpr")])
4679 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4680 ;; compiler from optimizing -0.0
4681 (define_insn "copysign<mode>3_fcpsgn"
4682   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4683         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4684                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4685                      UNSPEC_COPYSIGN))]
4686   "TARGET_<MODE>_FPR && TARGET_CMPB"
4687   "@
4688    fcpsgn %0,%2,%1
4689    xscpsgndp %x0,%x2,%x1"
4690   [(set_attr "type" "fpsimple")])
4692 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4693 ;; fsel instruction and some auxiliary computations.  Then we just have a
4694 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4695 ;; combine.
4696 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4697 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4698 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4699 ;; define_splits to make them if made by combine.  On VSX machines we have the
4700 ;; min/max instructions.
4702 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4703 ;; to allow either DF/SF to use only traditional registers.
4705 (define_expand "s<minmax><mode>3"
4706   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4707         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4708                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4709   "TARGET_MINMAX_<MODE>"
4711   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4712   DONE;
4715 (define_insn "*s<minmax><mode>3_vsx"
4716   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4717         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4718                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4719   "TARGET_VSX && TARGET_<MODE>_FPR"
4721   return (TARGET_P9_MINMAX
4722           ? "xs<minmax>cdp %x0,%x1,%x2"
4723           : "xs<minmax>dp %x0,%x1,%x2");
4725   [(set_attr "type" "fp")])
4727 ;; The conditional move instructions allow us to perform max and min operations
4728 ;; even when we don't have the appropriate max/min instruction using the FSEL
4729 ;; instruction.
4731 (define_insn_and_split "*s<minmax><mode>3_fpr"
4732   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4733         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4734                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4735   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4736   "#"
4737   "&& 1"
4738   [(const_int 0)]
4740   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4741   DONE;
4744 (define_expand "mov<mode>cc"
4745    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4746          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4747                            (match_operand:GPR 2 "gpc_reg_operand" "")
4748                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4749   "TARGET_ISEL<sel>"
4750   "
4752   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4753     DONE;
4754   else
4755     FAIL;
4758 ;; We use the BASE_REGS for the isel input operands because, if rA is
4759 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4760 ;; because we may switch the operands and rB may end up being rA.
4762 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4763 ;; leave out the mode in operand 4 and use one pattern, but reload can
4764 ;; change the mode underneath our feet and then gets confused trying
4765 ;; to reload the value.
4766 (define_insn "isel_signed_<mode>"
4767   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4768         (if_then_else:GPR
4769          (match_operator 1 "scc_comparison_operator"
4770                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4771                           (const_int 0)])
4772          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4773          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4774   "TARGET_ISEL<sel>"
4775   "*
4776 { return output_isel (operands); }"
4777   [(set_attr "type" "isel")
4778    (set_attr "length" "4")])
4780 (define_insn "isel_unsigned_<mode>"
4781   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4782         (if_then_else:GPR
4783          (match_operator 1 "scc_comparison_operator"
4784                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4785                           (const_int 0)])
4786          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4787          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4788   "TARGET_ISEL<sel>"
4789   "*
4790 { return output_isel (operands); }"
4791   [(set_attr "type" "isel")
4792    (set_attr "length" "4")])
4794 ;; These patterns can be useful for combine; they let combine know that
4795 ;; isel can handle reversed comparisons so long as the operands are
4796 ;; registers.
4798 (define_insn "*isel_reversed_signed_<mode>"
4799   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4800         (if_then_else:GPR
4801          (match_operator 1 "scc_rev_comparison_operator"
4802                          [(match_operand:CC 4 "cc_reg_operand" "y")
4803                           (const_int 0)])
4804          (match_operand:GPR 2 "gpc_reg_operand" "b")
4805          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4806   "TARGET_ISEL<sel>"
4807   "*
4808 { return output_isel (operands); }"
4809   [(set_attr "type" "isel")
4810    (set_attr "length" "4")])
4812 (define_insn "*isel_reversed_unsigned_<mode>"
4813   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4814         (if_then_else:GPR
4815          (match_operator 1 "scc_rev_comparison_operator"
4816                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4817                           (const_int 0)])
4818          (match_operand:GPR 2 "gpc_reg_operand" "b")
4819          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4820   "TARGET_ISEL<sel>"
4821   "*
4822 { return output_isel (operands); }"
4823   [(set_attr "type" "isel")
4824    (set_attr "length" "4")])
4826 ;; Floating point conditional move
4827 (define_expand "mov<mode>cc"
4828    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4829          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4830                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4831                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4832   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4833   "
4835   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4836     DONE;
4837   else
4838     FAIL;
4841 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4842   [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4843         (if_then_else:SFDF
4844          (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4845              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4846          (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4847          (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4848   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4849   "fsel %0,%1,%2,%3"
4850   [(set_attr "type" "fp")])
4852 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4853   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4854         (if_then_else:SFDF
4855          (match_operator:CCFP 1 "fpmask_comparison_operator"
4856                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4857                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4858          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4859          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4860    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4861   "TARGET_P9_MINMAX"
4862   "#"
4863   ""
4864   [(set (match_dup 6)
4865         (if_then_else:V2DI (match_dup 1)
4866                            (match_dup 7)
4867                            (match_dup 8)))
4868    (set (match_dup 0)
4869         (if_then_else:SFDF (ne (match_dup 6)
4870                                (match_dup 8))
4871                            (match_dup 4)
4872                            (match_dup 5)))]
4874   if (GET_CODE (operands[6]) == SCRATCH)
4875     operands[6] = gen_reg_rtx (V2DImode);
4877   operands[7] = CONSTM1_RTX (V2DImode);
4878   operands[8] = CONST0_RTX (V2DImode);
4880  [(set_attr "length" "8")
4881   (set_attr "type" "vecperm")])
4883 (define_insn "*fpmask<mode>"
4884   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4885         (if_then_else:V2DI
4886          (match_operator:CCFP 1 "fpmask_comparison_operator"
4887                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4888                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4889          (match_operand:V2DI 4 "all_ones_constant" "")
4890          (match_operand:V2DI 5 "zero_constant" "")))]
4891   "TARGET_P9_MINMAX"
4892   "xscmp%V1dp %x0,%x2,%x3"
4893   [(set_attr "type" "fpcompare")])
4895 (define_insn "*xxsel<mode>"
4896   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4897         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4898                                (match_operand:V2DI 2 "zero_constant" ""))
4899                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4900                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4901   "TARGET_P9_MINMAX"
4902   "xxsel %x0,%x1,%x3,%x4"
4903   [(set_attr "type" "vecmove")])
4906 ;; Conversions to and from floating-point.
4908 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4909 ; don't want to support putting SImode in FPR registers.
4910 (define_insn "lfiwax"
4911   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4912         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4913                    UNSPEC_LFIWAX))]
4914   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4915   "@
4916    lfiwax %0,%y1
4917    lxsiwax %x0,%y1
4918    mtvsrwa %x0,%1"
4919   [(set_attr "type" "fpload,fpload,mffgpr")])
4921 ; This split must be run before register allocation because it allocates the
4922 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4923 ; it earlier to allow for the combiner to merge insns together where it might
4924 ; not be needed and also in case the insns are deleted as dead code.
4926 (define_insn_and_split "floatsi<mode>2_lfiwax"
4927   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4928         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4929    (clobber (match_scratch:DI 2 "=wi"))]
4930   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4931    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4932   "#"
4933   ""
4934   [(pc)]
4935   "
4937   rtx dest = operands[0];
4938   rtx src = operands[1];
4939   rtx tmp;
4941   if (!MEM_P (src) && TARGET_POWERPC64
4942       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4943     tmp = convert_to_mode (DImode, src, false);
4944   else
4945     {
4946       tmp = operands[2];
4947       if (GET_CODE (tmp) == SCRATCH)
4948         tmp = gen_reg_rtx (DImode);
4949       if (MEM_P (src))
4950         {
4951           src = rs6000_address_for_fpconvert (src);
4952           emit_insn (gen_lfiwax (tmp, src));
4953         }
4954       else
4955         {
4956           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4957           emit_move_insn (stack, src);
4958           emit_insn (gen_lfiwax (tmp, stack));
4959         }
4960     }
4961   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4962   DONE;
4964   [(set_attr "length" "12")
4965    (set_attr "type" "fpload")])
4967 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4968   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4969         (float:SFDF
4970          (sign_extend:DI
4971           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
4972    (clobber (match_scratch:DI 2 "=wi"))]
4973   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4974    && <SI_CONVERT_FP>"
4975   "#"
4976   ""
4977   [(pc)]
4978   "
4980   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4981   if (GET_CODE (operands[2]) == SCRATCH)
4982     operands[2] = gen_reg_rtx (DImode);
4983   emit_insn (gen_lfiwax (operands[2], operands[1]));
4984   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4985   DONE;
4987   [(set_attr "length" "8")
4988    (set_attr "type" "fpload")])
4990 (define_insn "lfiwzx"
4991   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4992         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4993                    UNSPEC_LFIWZX))]
4994   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4995   "@
4996    lfiwzx %0,%y1
4997    lxsiwzx %x0,%y1
4998    mtvsrwz %x0,%1"
4999   [(set_attr "type" "fpload,fpload,mftgpr")])
5001 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5002   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5003         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5004    (clobber (match_scratch:DI 2 "=wi"))]
5005   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5006    && <SI_CONVERT_FP>"
5007   "#"
5008   ""
5009   [(pc)]
5010   "
5012   rtx dest = operands[0];
5013   rtx src = operands[1];
5014   rtx tmp;
5016   if (!MEM_P (src) && TARGET_POWERPC64
5017       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5018     tmp = convert_to_mode (DImode, src, true);
5019   else
5020     {
5021       tmp = operands[2];
5022       if (GET_CODE (tmp) == SCRATCH)
5023         tmp = gen_reg_rtx (DImode);
5024       if (MEM_P (src))
5025         {
5026           src = rs6000_address_for_fpconvert (src);
5027           emit_insn (gen_lfiwzx (tmp, src));
5028         }
5029       else
5030         {
5031           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5032           emit_move_insn (stack, src);
5033           emit_insn (gen_lfiwzx (tmp, stack));
5034         }
5035     }
5036   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5037   DONE;
5039   [(set_attr "length" "12")
5040    (set_attr "type" "fpload")])
5042 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5043   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5044         (unsigned_float:SFDF
5045          (zero_extend:DI
5046           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5047    (clobber (match_scratch:DI 2 "=wi"))]
5048   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5049    && <SI_CONVERT_FP>"
5050   "#"
5051   ""
5052   [(pc)]
5053   "
5055   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5056   if (GET_CODE (operands[2]) == SCRATCH)
5057     operands[2] = gen_reg_rtx (DImode);
5058   emit_insn (gen_lfiwzx (operands[2], operands[1]));
5059   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5060   DONE;
5062   [(set_attr "length" "8")
5063    (set_attr "type" "fpload")])
5065 ; For each of these conversions, there is a define_expand, a define_insn
5066 ; with a '#' template, and a define_split (with C code).  The idea is
5067 ; to allow constant folding with the template of the define_insn,
5068 ; then to have the insns split later (between sched1 and final).
5070 (define_expand "floatsidf2"
5071   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5072                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5073               (use (match_dup 2))
5074               (use (match_dup 3))
5075               (clobber (match_dup 4))
5076               (clobber (match_dup 5))
5077               (clobber (match_dup 6))])]
5078   "TARGET_HARD_FLOAT 
5079    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5080   "
5082   if (TARGET_E500_DOUBLE)
5083     {
5084       if (!REG_P (operands[1]))
5085         operands[1] = force_reg (SImode, operands[1]);
5086       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5087       DONE;
5088     }
5089   else if (TARGET_LFIWAX && TARGET_FCFID)
5090     {
5091       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5092       DONE;
5093     }
5094   else if (TARGET_FCFID)
5095     {
5096       rtx dreg = operands[1];
5097       if (!REG_P (dreg))
5098         dreg = force_reg (SImode, dreg);
5099       dreg = convert_to_mode (DImode, dreg, false);
5100       emit_insn (gen_floatdidf2 (operands[0], dreg));
5101       DONE;
5102     }
5104   if (!REG_P (operands[1]))
5105     operands[1] = force_reg (SImode, operands[1]);
5106   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5107   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5108   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5109   operands[5] = gen_reg_rtx (DFmode);
5110   operands[6] = gen_reg_rtx (SImode);
5113 (define_insn_and_split "*floatsidf2_internal"
5114   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5115         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5116    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5117    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5118    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5119    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5120    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5121   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5122   "#"
5123   ""
5124   [(pc)]
5125   "
5127   rtx lowword, highword;
5128   gcc_assert (MEM_P (operands[4]));
5129   highword = adjust_address (operands[4], SImode, 0);
5130   lowword = adjust_address (operands[4], SImode, 4);
5131   if (! WORDS_BIG_ENDIAN)
5132     std::swap (lowword, highword);
5134   emit_insn (gen_xorsi3 (operands[6], operands[1],
5135                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5136   emit_move_insn (lowword, operands[6]);
5137   emit_move_insn (highword, operands[2]);
5138   emit_move_insn (operands[5], operands[4]);
5139   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5140   DONE;
5142   [(set_attr "length" "24")
5143    (set_attr "type" "fp")])
5145 ;; If we don't have a direct conversion to single precision, don't enable this
5146 ;; conversion for 32-bit without fast math, because we don't have the insn to
5147 ;; generate the fixup swizzle to avoid double rounding problems.
5148 (define_expand "floatunssisf2"
5149   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5150         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5151   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5152    && (!TARGET_FPRS
5153        || (TARGET_FPRS
5154            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5155                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5156                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5157   "
5159   if (!TARGET_FPRS)
5160     {
5161       if (!REG_P (operands[1]))
5162         operands[1] = force_reg (SImode, operands[1]);
5163     }
5164   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5165     {
5166       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5167       DONE;
5168     }
5169   else
5170     {
5171       rtx dreg = operands[1];
5172       if (!REG_P (dreg))
5173         dreg = force_reg (SImode, dreg);
5174       dreg = convert_to_mode (DImode, dreg, true);
5175       emit_insn (gen_floatdisf2 (operands[0], dreg));
5176       DONE;
5177     }
5180 (define_expand "floatunssidf2"
5181   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5182                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5183               (use (match_dup 2))
5184               (use (match_dup 3))
5185               (clobber (match_dup 4))
5186               (clobber (match_dup 5))])]
5187   "TARGET_HARD_FLOAT
5188    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5189   "
5191   if (TARGET_E500_DOUBLE)
5192     {
5193       if (!REG_P (operands[1]))
5194         operands[1] = force_reg (SImode, operands[1]);
5195       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5196       DONE;
5197     }
5198   else if (TARGET_LFIWZX && TARGET_FCFID)
5199     {
5200       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5201       DONE;
5202     }
5203   else if (TARGET_FCFID)
5204     {
5205       rtx dreg = operands[1];
5206       if (!REG_P (dreg))
5207         dreg = force_reg (SImode, dreg);
5208       dreg = convert_to_mode (DImode, dreg, true);
5209       emit_insn (gen_floatdidf2 (operands[0], dreg));
5210       DONE;
5211     }
5213   if (!REG_P (operands[1]))
5214     operands[1] = force_reg (SImode, operands[1]);
5215   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5216   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5217   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5218   operands[5] = gen_reg_rtx (DFmode);
5221 (define_insn_and_split "*floatunssidf2_internal"
5222   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5223         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5224    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5225    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5226    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5227    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5228   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5229    && !(TARGET_FCFID && TARGET_POWERPC64)"
5230   "#"
5231   ""
5232   [(pc)]
5233   "
5235   rtx lowword, highword;
5236   gcc_assert (MEM_P (operands[4]));
5237   highword = adjust_address (operands[4], SImode, 0);
5238   lowword = adjust_address (operands[4], SImode, 4);
5239   if (! WORDS_BIG_ENDIAN)
5240     std::swap (lowword, highword);
5242   emit_move_insn (lowword, operands[1]);
5243   emit_move_insn (highword, operands[2]);
5244   emit_move_insn (operands[5], operands[4]);
5245   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5246   DONE;
5248   [(set_attr "length" "20")
5249    (set_attr "type" "fp")])
5251 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5252 ;; vector registers.  At the moment, QI/HImode are not allowed in floating
5253 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5254 ;; half-word instructions.
5256 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5257   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5258                    (float:FP_ISA3
5259                     (match_operand:QHI 1 "input_operand")))
5260               (clobber (match_scratch:DI 2))
5261               (clobber (match_scratch:DI 3))])]
5262   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5264   if (MEM_P (operands[1]))
5265     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5268 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5269   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5270         (float:FP_ISA3
5271          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5272    (clobber (match_scratch:DI 2 "=wi,v"))
5273    (clobber (match_scratch:DI 3 "=r,X"))]
5274   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5275    && TARGET_UPPER_REGS_DI"
5276   "#"
5277   "&& reload_completed"
5278   [(const_int 0)]
5280   rtx result = operands[0];
5281   rtx input = operands[1];
5282   rtx di = operands[2];
5284   if (!MEM_P (input))
5285     {
5286       rtx tmp = operands[3];
5287       emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5288       emit_move_insn (di, tmp);
5289     }
5290   else
5291     {
5292       machine_mode vmode;
5293       rtx di_vector;
5295       emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5297       if (<MODE>mode == QImode)
5298         vmode = V16QImode;
5299       else if (<MODE>mode == HImode)
5300         vmode = V8HImode;
5301       else
5302         gcc_unreachable ();
5304       di_vector = gen_rtx_REG (vmode, REGNO (di));
5305       emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5306     }
5308   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5309   DONE;
5312 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5313   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5314                    (unsigned_float:FP_ISA3
5315                     (match_operand:QHI 1 "input_operand" "")))
5316               (clobber (match_scratch:DI 2 ""))
5317               (clobber (match_scratch:DI 3 ""))])]
5318   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5320   if (MEM_P (operands[1]))
5321     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5324 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5325   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5326         (unsigned_float:FP_ISA3
5327          (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5328    (clobber (match_scratch:DI 2 "=wi,wi"))
5329    (clobber (match_scratch:DI 3 "=r,X"))]
5330   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5331   "#"
5332   "&& reload_completed"
5333   [(const_int 0)]
5335   rtx result = operands[0];
5336   rtx input = operands[1];
5337   rtx di = operands[2];
5338   rtx tmp = operands[3];
5340   if (!MEM_P (input))
5341     {
5342       emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5343       emit_move_insn (di, tmp);
5344     }
5345   else
5346     emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5348   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5349   DONE;
5352 (define_expand "fix_trunc<mode>si2"
5353   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5354         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5355   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5356   "
5358   if (!<E500_CONVERT>)
5359     {
5360       rtx src = force_reg (SFmode, operands[1]);
5362       if (TARGET_STFIWX)
5363         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5364       else
5365         {
5366           rtx tmp = gen_reg_rtx (DImode);
5367           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5368           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5369                                                       tmp, stack));
5370         }
5371       DONE;
5372     }
5375 ; Like the convert to float patterns, this insn must be split before
5376 ; register allocation so that it can allocate the memory slot if it
5377 ; needed
5378 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5379   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5380         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5381    (clobber (match_scratch:DI 2 "=d"))]
5382   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5383    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5384    && TARGET_STFIWX && can_create_pseudo_p ()"
5385   "#"
5386   ""
5387   [(pc)]
5389   rtx dest = operands[0];
5390   rtx src = operands[1];
5391   rtx tmp = operands[2];
5393   if (GET_CODE (tmp) == SCRATCH)
5394     tmp = gen_reg_rtx (DImode);
5396   emit_insn (gen_fctiwz_<mode> (tmp, src));
5397   if (MEM_P (dest))
5398     {
5399       dest = rs6000_address_for_fpconvert (dest);
5400       emit_insn (gen_stfiwx (dest, tmp));
5401       DONE;
5402     }
5403   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5404     {
5405       dest = gen_lowpart (DImode, dest);
5406       emit_move_insn (dest, tmp);
5407       DONE;
5408     }
5409   else
5410     {
5411       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5412       emit_insn (gen_stfiwx (stack, tmp));
5413       emit_move_insn (dest, stack);
5414       DONE;
5415     }
5417   [(set_attr "length" "12")
5418    (set_attr "type" "fp")])
5420 (define_insn_and_split "fix_trunc<mode>si2_internal"
5421   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5422         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5423    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5424    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5425   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5426   "#"
5427   ""
5428   [(pc)]
5429   "
5431   rtx lowword;
5432   gcc_assert (MEM_P (operands[3]));
5433   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5435   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5436   emit_move_insn (operands[3], operands[2]);
5437   emit_move_insn (operands[0], lowword);
5438   DONE;
5440   [(set_attr "length" "16")
5441    (set_attr "type" "fp")])
5443 (define_expand "fix_trunc<mode>di2"
5444   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5445         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5446   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5447    && TARGET_FCFID"
5448   "")
5450 (define_insn "*fix_trunc<mode>di2_fctidz"
5451   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5452         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5453   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5454     && TARGET_FCFID"
5455   "@
5456    fctidz %0,%1
5457    xscvdpsxds %x0,%x1"
5458   [(set_attr "type" "fp")])
5460 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5461   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5462    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5463   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5465   rtx op0 = operands[0];
5466   rtx op1 = operands[1];
5467   rtx di_tmp = gen_reg_rtx (DImode);
5469   if (MEM_P (op0))
5470     op0 = rs6000_address_for_fpconvert (op0);
5472   emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5473   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5474   DONE;
5477 (define_expand "fixuns_trunc<mode>si2"
5478   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5479         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5480   "TARGET_HARD_FLOAT
5481    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5482        || <E500_CONVERT>)"
5483   "
5485   if (!<E500_CONVERT>)
5486     {
5487       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5488       DONE;
5489     }
5492 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5493   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5494         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5495    (clobber (match_scratch:DI 2 "=d"))]
5496   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5497    && TARGET_STFIWX && can_create_pseudo_p ()"
5498   "#"
5499   ""
5500   [(pc)]
5502   rtx dest = operands[0];
5503   rtx src = operands[1];
5504   rtx tmp = operands[2];
5506   if (GET_CODE (tmp) == SCRATCH)
5507     tmp = gen_reg_rtx (DImode);
5509   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5510   if (MEM_P (dest))
5511     {
5512       dest = rs6000_address_for_fpconvert (dest);
5513       emit_insn (gen_stfiwx (dest, tmp));
5514       DONE;
5515     }
5516   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5517     {
5518       dest = gen_lowpart (DImode, dest);
5519       emit_move_insn (dest, tmp);
5520       DONE;
5521     }
5522   else
5523     {
5524       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5525       emit_insn (gen_stfiwx (stack, tmp));
5526       emit_move_insn (dest, stack);
5527       DONE;
5528     }
5530   [(set_attr "length" "12")
5531    (set_attr "type" "fp")])
5533 (define_expand "fixuns_trunc<mode>di2"
5534   [(set (match_operand:DI 0 "register_operand" "")
5535         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5536   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5537   "")
5539 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5540   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5541         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5542   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5543     && TARGET_FCTIDUZ"
5544   "@
5545    fctiduz %0,%1
5546    xscvdpuxds %x0,%x1"
5547   [(set_attr "type" "fp")])
5549 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5550   [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5551    (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5552   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5554   rtx op0 = operands[0];
5555   rtx op1 = operands[1];
5556   rtx di_tmp = gen_reg_rtx (DImode);
5558   if (MEM_P (op0))
5559     op0 = rs6000_address_for_fpconvert (op0);
5561   emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5562   emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5563   DONE;
5566 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5567 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5568 ; because the first makes it clear that operand 0 is not live
5569 ; before the instruction.
5570 (define_insn "fctiwz_<mode>"
5571   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5572         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5573                    UNSPEC_FCTIWZ))]
5574   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5575   "@
5576    fctiwz %0,%1
5577    xscvdpsxws %x0,%x1"
5578   [(set_attr "type" "fp")])
5580 (define_insn "fctiwuz_<mode>"
5581   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5582         (unspec:DI [(unsigned_fix:SI
5583                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5584                    UNSPEC_FCTIWUZ))]
5585   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5586   "@
5587    fctiwuz %0,%1
5588    xscvdpuxws %x0,%x1"
5589   [(set_attr "type" "fp")])
5591 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5592 ;; since the friz instruction does not truncate the value if the floating
5593 ;; point value is < LONG_MIN or > LONG_MAX.
5594 (define_insn "*friz"
5595   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5596         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5597   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5598    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5599   "@
5600    friz %0,%1
5601    xsrdpiz %x0,%x1"
5602   [(set_attr "type" "fp")])
5604 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5605 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5606 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5607 ;; extend it, store it back on the stack from the GPR, load it back into the
5608 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5609 ;; disable using store and load to sign/zero extend the value.
5610 (define_insn_and_split "*round32<mode>2_fprs"
5611   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5612         (float:SFDF
5613          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5614    (clobber (match_scratch:DI 2 "=d"))
5615    (clobber (match_scratch:DI 3 "=d"))]
5616   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5617    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5618    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5619   "#"
5620   ""
5621   [(pc)]
5623   rtx dest = operands[0];
5624   rtx src = operands[1];
5625   rtx tmp1 = operands[2];
5626   rtx tmp2 = operands[3];
5627   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5629   if (GET_CODE (tmp1) == SCRATCH)
5630     tmp1 = gen_reg_rtx (DImode);
5631   if (GET_CODE (tmp2) == SCRATCH)
5632     tmp2 = gen_reg_rtx (DImode);
5634   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5635   emit_insn (gen_stfiwx (stack, tmp1));
5636   emit_insn (gen_lfiwax (tmp2, stack));
5637   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5638   DONE;
5640   [(set_attr "type" "fpload")
5641    (set_attr "length" "16")])
5643 (define_insn_and_split "*roundu32<mode>2_fprs"
5644   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5645         (unsigned_float:SFDF
5646          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5647    (clobber (match_scratch:DI 2 "=d"))
5648    (clobber (match_scratch:DI 3 "=d"))]
5649   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5650    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5651    && can_create_pseudo_p ()"
5652   "#"
5653   ""
5654   [(pc)]
5656   rtx dest = operands[0];
5657   rtx src = operands[1];
5658   rtx tmp1 = operands[2];
5659   rtx tmp2 = operands[3];
5660   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5662   if (GET_CODE (tmp1) == SCRATCH)
5663     tmp1 = gen_reg_rtx (DImode);
5664   if (GET_CODE (tmp2) == SCRATCH)
5665     tmp2 = gen_reg_rtx (DImode);
5667   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5668   emit_insn (gen_stfiwx (stack, tmp1));
5669   emit_insn (gen_lfiwzx (tmp2, stack));
5670   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5671   DONE;
5673   [(set_attr "type" "fpload")
5674    (set_attr "length" "16")])
5676 ;; No VSX equivalent to fctid
5677 (define_insn "lrint<mode>di2"
5678   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5679         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5680                    UNSPEC_FCTID))]
5681   "TARGET_<MODE>_FPR && TARGET_FPRND"
5682   "fctid %0,%1"
5683   [(set_attr "type" "fp")])
5685 (define_insn "btrunc<mode>2"
5686   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5687         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5688                      UNSPEC_FRIZ))]
5689   "TARGET_<MODE>_FPR && TARGET_FPRND"
5690   "@
5691    friz %0,%1
5692    xsrdpiz %x0,%x1"
5693   [(set_attr "type" "fp")
5694    (set_attr "fp_type" "fp_addsub_<Fs>")])
5696 (define_insn "ceil<mode>2"
5697   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5698         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5699                      UNSPEC_FRIP))]
5700   "TARGET_<MODE>_FPR && TARGET_FPRND"
5701   "@
5702    frip %0,%1
5703    xsrdpip %x0,%x1"
5704   [(set_attr "type" "fp")
5705    (set_attr "fp_type" "fp_addsub_<Fs>")])
5707 (define_insn "floor<mode>2"
5708   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5709         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5710                      UNSPEC_FRIM))]
5711   "TARGET_<MODE>_FPR && TARGET_FPRND"
5712   "@
5713    frim %0,%1
5714    xsrdpim %x0,%x1"
5715   [(set_attr "type" "fp")
5716    (set_attr "fp_type" "fp_addsub_<Fs>")])
5718 ;; No VSX equivalent to frin
5719 (define_insn "round<mode>2"
5720   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5721         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5722                      UNSPEC_FRIN))]
5723   "TARGET_<MODE>_FPR && TARGET_FPRND"
5724   "frin %0,%1"
5725   [(set_attr "type" "fp")
5726    (set_attr "fp_type" "fp_addsub_<Fs>")])
5728 (define_insn "*xsrdpi<mode>2"
5729   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5730         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5731                      UNSPEC_XSRDPI))]
5732   "TARGET_<MODE>_FPR && TARGET_VSX"
5733   "xsrdpi %x0,%x1"
5734   [(set_attr "type" "fp")
5735    (set_attr "fp_type" "fp_addsub_<Fs>")])
5737 (define_expand "lround<mode>di2"
5738   [(set (match_dup 2)
5739         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5740                      UNSPEC_XSRDPI))
5741    (set (match_operand:DI 0 "gpc_reg_operand" "")
5742         (unspec:DI [(match_dup 2)]
5743                    UNSPEC_FCTID))]
5744   "TARGET_<MODE>_FPR && TARGET_VSX"
5746   operands[2] = gen_reg_rtx (<MODE>mode);
5749 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5750 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5751 ; is only generated for Power8 or later.
5752 (define_insn "stfiwx"
5753   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5754         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5755                    UNSPEC_STFIWX))]
5756   "TARGET_PPC_GFXOPT"
5757   "@
5758    stfiwx %1,%y0
5759    stxsiwx %x1,%y0"
5760   [(set_attr "type" "fpstore")])
5762 ;; If we don't have a direct conversion to single precision, don't enable this
5763 ;; conversion for 32-bit without fast math, because we don't have the insn to
5764 ;; generate the fixup swizzle to avoid double rounding problems.
5765 (define_expand "floatsisf2"
5766   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5767         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5768   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5769    && (!TARGET_FPRS
5770        || (TARGET_FPRS
5771            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5772                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5773                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5774   "
5776   if (!TARGET_FPRS)
5777     {
5778       if (!REG_P (operands[1]))
5779         operands[1] = force_reg (SImode, operands[1]);
5780     }
5781   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5782     {
5783       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5784       DONE;
5785     }
5786   else if (TARGET_FCFID && TARGET_LFIWAX)
5787     {
5788       rtx dfreg = gen_reg_rtx (DFmode);
5789       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5790       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5791       DONE;
5792     }
5793   else
5794     {
5795       rtx dreg = operands[1];
5796       if (!REG_P (dreg))
5797         dreg = force_reg (SImode, dreg);
5798       dreg = convert_to_mode (DImode, dreg, false);
5799       emit_insn (gen_floatdisf2 (operands[0], dreg));
5800       DONE;
5801     }
5804 (define_expand "floatdidf2"
5805   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5806         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5807   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5808   "")
5810 (define_insn "*floatdidf2_fpr"
5811   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5812         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5813   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5814   "@
5815    fcfid %0,%1
5816    xscvsxddp %x0,%x1"
5817   [(set_attr "type" "fp")])
5819 ; Allow the combiner to merge source memory operands to the conversion so that
5820 ; the optimizer/register allocator doesn't try to load the value too early in a
5821 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5822 ; hit.  We will split after reload to avoid the trip through the GPRs
5824 (define_insn_and_split "*floatdidf2_mem"
5825   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5826         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5827    (clobber (match_scratch:DI 2 "=d,wi"))]
5828   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5829   "#"
5830   "&& reload_completed"
5831   [(set (match_dup 2) (match_dup 1))
5832    (set (match_dup 0) (float:DF (match_dup 2)))]
5833   ""
5834   [(set_attr "length" "8")
5835    (set_attr "type" "fpload")])
5837 (define_expand "floatunsdidf2"
5838   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5839         (unsigned_float:DF
5840          (match_operand:DI 1 "gpc_reg_operand" "")))]
5841   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5842   "")
5844 (define_insn "*floatunsdidf2_fcfidu"
5845   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5846         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5847   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5848   "@
5849    fcfidu %0,%1
5850    xscvuxddp %x0,%x1"
5851   [(set_attr "type" "fp")
5852    (set_attr "length" "4")])
5854 (define_insn_and_split "*floatunsdidf2_mem"
5855   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5856         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5857    (clobber (match_scratch:DI 2 "=d,wi"))]
5858   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5859   "#"
5860   "&& reload_completed"
5861   [(set (match_dup 2) (match_dup 1))
5862    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5863   ""
5864   [(set_attr "length" "8")
5865    (set_attr "type" "fpload")])
5867 (define_expand "floatdisf2"
5868   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5869         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5870   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5871    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5872   "
5874   if (!TARGET_FCFIDS)
5875     {
5876       rtx val = operands[1];
5877       if (!flag_unsafe_math_optimizations)
5878         {
5879           rtx label = gen_label_rtx ();
5880           val = gen_reg_rtx (DImode);
5881           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5882           emit_label (label);
5883         }
5884       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5885       DONE;
5886     }
5889 (define_insn "floatdisf2_fcfids"
5890   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5891         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5892   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5893    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5894   "@
5895    fcfids %0,%1
5896    xscvsxdsp %x0,%x1"
5897   [(set_attr "type" "fp")])
5899 (define_insn_and_split "*floatdisf2_mem"
5900   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5901         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5902    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5903   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5904    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5905   "#"
5906   "&& reload_completed"
5907   [(pc)]
5908   "
5910   emit_move_insn (operands[2], operands[1]);
5911   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5912   DONE;
5914   [(set_attr "length" "8")])
5916 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5917 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5918 ;; from double rounding.
5919 ;; Instead of creating a new cpu type for two FP operations, just use fp
5920 (define_insn_and_split "floatdisf2_internal1"
5921   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5922         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5923    (clobber (match_scratch:DF 2 "=d"))]
5924   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5925    && !TARGET_FCFIDS"
5926   "#"
5927   "&& reload_completed"
5928   [(set (match_dup 2)
5929         (float:DF (match_dup 1)))
5930    (set (match_dup 0)
5931         (float_truncate:SF (match_dup 2)))]
5932   ""
5933   [(set_attr "length" "8")
5934    (set_attr "type" "fp")])
5936 ;; Twiddles bits to avoid double rounding.
5937 ;; Bits that might be truncated when converting to DFmode are replaced
5938 ;; by a bit that won't be lost at that stage, but is below the SFmode
5939 ;; rounding position.
5940 (define_expand "floatdisf2_internal2"
5941   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5942                                               (const_int 53)))
5943               (clobber (reg:DI CA_REGNO))])
5944    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5945                                            (const_int 2047)))
5946    (set (match_dup 3) (plus:DI (match_dup 3)
5947                                (const_int 1)))
5948    (set (match_dup 0) (plus:DI (match_dup 0)
5949                                (const_int 2047)))
5950    (set (match_dup 4) (compare:CCUNS (match_dup 3)
5951                                      (const_int 2)))
5952    (set (match_dup 0) (ior:DI (match_dup 0)
5953                               (match_dup 1)))
5954    (set (match_dup 0) (and:DI (match_dup 0)
5955                               (const_int -2048)))
5956    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5957                            (label_ref (match_operand:DI 2 "" ""))
5958                            (pc)))
5959    (set (match_dup 0) (match_dup 1))]
5960   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5961    && !TARGET_FCFIDS"
5962   "
5964   operands[3] = gen_reg_rtx (DImode);
5965   operands[4] = gen_reg_rtx (CCUNSmode);
5968 (define_expand "floatunsdisf2"
5969   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5970         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5971   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5972    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5973   "")
5975 (define_insn "floatunsdisf2_fcfidus"
5976   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5977         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5978   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5979    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5980   "@
5981    fcfidus %0,%1
5982    xscvuxdsp %x0,%x1"
5983   [(set_attr "type" "fp")])
5985 (define_insn_and_split "*floatunsdisf2_mem"
5986   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5987         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5988    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5989   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5990    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5991   "#"
5992   "&& reload_completed"
5993   [(pc)]
5994   "
5996   emit_move_insn (operands[2], operands[1]);
5997   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5998   DONE;
6000   [(set_attr "length" "8")
6001    (set_attr "type" "fpload")])
6003 ;; Define the TImode operations that can be done in a small number
6004 ;; of instructions.  The & constraints are to prevent the register
6005 ;; allocator from allocating registers that overlap with the inputs
6006 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6007 ;; also allow for the output being the same as one of the inputs.
6009 (define_expand "addti3"
6010   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6011         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6012                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6013   "TARGET_64BIT"
6015   rtx lo0 = gen_lowpart (DImode, operands[0]);
6016   rtx lo1 = gen_lowpart (DImode, operands[1]);
6017   rtx lo2 = gen_lowpart (DImode, operands[2]);
6018   rtx hi0 = gen_highpart (DImode, operands[0]);
6019   rtx hi1 = gen_highpart (DImode, operands[1]);
6020   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6022   if (!reg_or_short_operand (lo2, DImode))
6023     lo2 = force_reg (DImode, lo2);
6024   if (!adde_operand (hi2, DImode))
6025     hi2 = force_reg (DImode, hi2);
6027   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6028   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6029   DONE;
6032 (define_expand "subti3"
6033   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6034         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6035                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6036   "TARGET_64BIT"
6038   rtx lo0 = gen_lowpart (DImode, operands[0]);
6039   rtx lo1 = gen_lowpart (DImode, operands[1]);
6040   rtx lo2 = gen_lowpart (DImode, operands[2]);
6041   rtx hi0 = gen_highpart (DImode, operands[0]);
6042   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6043   rtx hi2 = gen_highpart (DImode, operands[2]);
6045   if (!reg_or_short_operand (lo1, DImode))
6046     lo1 = force_reg (DImode, lo1);
6047   if (!adde_operand (hi1, DImode))
6048     hi1 = force_reg (DImode, hi1);
6050   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6051   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6052   DONE;
6055 ;; 128-bit logical operations expanders
6057 (define_expand "and<mode>3"
6058   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6059         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6060                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6061   ""
6062   "")
6064 (define_expand "ior<mode>3"
6065   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6066         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6067                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6068   ""
6069   "")
6071 (define_expand "xor<mode>3"
6072   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6073         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6074                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6075   ""
6076   "")
6078 (define_expand "one_cmpl<mode>2"
6079   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6080         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6081   ""
6082   "")
6084 (define_expand "nor<mode>3"
6085   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6086         (and:BOOL_128
6087          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6088          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6089   ""
6090   "")
6092 (define_expand "andc<mode>3"
6093   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6094         (and:BOOL_128
6095          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6096          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6097   ""
6098   "")
6100 ;; Power8 vector logical instructions.
6101 (define_expand "eqv<mode>3"
6102   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6103         (not:BOOL_128
6104          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6105                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6106   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6107   "")
6109 ;; Rewrite nand into canonical form
6110 (define_expand "nand<mode>3"
6111   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6112         (ior:BOOL_128
6113          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6114          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6115   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6116   "")
6118 ;; The canonical form is to have the negated element first, so we need to
6119 ;; reverse arguments.
6120 (define_expand "orc<mode>3"
6121   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6122         (ior:BOOL_128
6123          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6124          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6125   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6126   "")
6128 ;; 128-bit logical operations insns and split operations
6129 (define_insn_and_split "*and<mode>3_internal"
6130   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6131         (and:BOOL_128
6132          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6133          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6134   ""
6136   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6137     return "xxland %x0,%x1,%x2";
6139   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6140     return "vand %0,%1,%2";
6142   return "#";
6144   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6145   [(const_int 0)]
6147   rs6000_split_logical (operands, AND, false, false, false);
6148   DONE;
6150   [(set (attr "type")
6151       (if_then_else
6152         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6153         (const_string "veclogical")
6154         (const_string "integer")))
6155    (set (attr "length")
6156       (if_then_else
6157         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6158         (const_string "4")
6159         (if_then_else
6160          (match_test "TARGET_POWERPC64")
6161          (const_string "8")
6162          (const_string "16"))))])
6164 ;; 128-bit IOR/XOR
6165 (define_insn_and_split "*bool<mode>3_internal"
6166   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6167         (match_operator:BOOL_128 3 "boolean_or_operator"
6168          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6169           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6170   ""
6172   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6173     return "xxl%q3 %x0,%x1,%x2";
6175   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6176     return "v%q3 %0,%1,%2";
6178   return "#";
6180   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6181   [(const_int 0)]
6183   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6184   DONE;
6186   [(set (attr "type")
6187       (if_then_else
6188         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6189         (const_string "veclogical")
6190         (const_string "integer")))
6191    (set (attr "length")
6192       (if_then_else
6193         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6194         (const_string "4")
6195         (if_then_else
6196          (match_test "TARGET_POWERPC64")
6197          (const_string "8")
6198          (const_string "16"))))])
6200 ;; 128-bit ANDC/ORC
6201 (define_insn_and_split "*boolc<mode>3_internal1"
6202   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6203         (match_operator:BOOL_128 3 "boolean_operator"
6204          [(not:BOOL_128
6205            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6206           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6207   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6209   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6210     return "xxl%q3 %x0,%x1,%x2";
6212   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6213     return "v%q3 %0,%1,%2";
6215   return "#";
6217   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6218    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6219   [(const_int 0)]
6221   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6222   DONE;
6224   [(set (attr "type")
6225       (if_then_else
6226         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6227         (const_string "veclogical")
6228         (const_string "integer")))
6229    (set (attr "length")
6230       (if_then_else
6231         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6232         (const_string "4")
6233         (if_then_else
6234          (match_test "TARGET_POWERPC64")
6235          (const_string "8")
6236          (const_string "16"))))])
6238 (define_insn_and_split "*boolc<mode>3_internal2"
6239   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6240         (match_operator:TI2 3 "boolean_operator"
6241          [(not:TI2
6242            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6243           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6244   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6245   "#"
6246   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6247   [(const_int 0)]
6249   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6250   DONE;
6252   [(set_attr "type" "integer")
6253    (set (attr "length")
6254         (if_then_else
6255          (match_test "TARGET_POWERPC64")
6256          (const_string "8")
6257          (const_string "16")))])
6259 ;; 128-bit NAND/NOR
6260 (define_insn_and_split "*boolcc<mode>3_internal1"
6261   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6262         (match_operator:BOOL_128 3 "boolean_operator"
6263          [(not:BOOL_128
6264            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6265           (not:BOOL_128
6266            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6267   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6269   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6270     return "xxl%q3 %x0,%x1,%x2";
6272   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6273     return "v%q3 %0,%1,%2";
6275   return "#";
6277   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6278    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6279   [(const_int 0)]
6281   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6282   DONE;
6284   [(set (attr "type")
6285       (if_then_else
6286         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6287         (const_string "veclogical")
6288         (const_string "integer")))
6289    (set (attr "length")
6290       (if_then_else
6291         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6292         (const_string "4")
6293         (if_then_else
6294          (match_test "TARGET_POWERPC64")
6295          (const_string "8")
6296          (const_string "16"))))])
6298 (define_insn_and_split "*boolcc<mode>3_internal2"
6299   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6300         (match_operator:TI2 3 "boolean_operator"
6301          [(not:TI2
6302            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6303           (not:TI2
6304            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6305   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6306   "#"
6307   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6308   [(const_int 0)]
6310   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6311   DONE;
6313   [(set_attr "type" "integer")
6314    (set (attr "length")
6315         (if_then_else
6316          (match_test "TARGET_POWERPC64")
6317          (const_string "8")
6318          (const_string "16")))])
6321 ;; 128-bit EQV
6322 (define_insn_and_split "*eqv<mode>3_internal1"
6323   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6324         (not:BOOL_128
6325          (xor:BOOL_128
6326           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6327           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6328   "TARGET_P8_VECTOR"
6330   if (vsx_register_operand (operands[0], <MODE>mode))
6331     return "xxleqv %x0,%x1,%x2";
6333   return "#";
6335   "TARGET_P8_VECTOR && reload_completed
6336    && int_reg_operand (operands[0], <MODE>mode)"
6337   [(const_int 0)]
6339   rs6000_split_logical (operands, XOR, true, false, false);
6340   DONE;
6342   [(set (attr "type")
6343       (if_then_else
6344         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6345         (const_string "veclogical")
6346         (const_string "integer")))
6347    (set (attr "length")
6348       (if_then_else
6349         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6350         (const_string "4")
6351         (if_then_else
6352          (match_test "TARGET_POWERPC64")
6353          (const_string "8")
6354          (const_string "16"))))])
6356 (define_insn_and_split "*eqv<mode>3_internal2"
6357   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6358         (not:TI2
6359          (xor:TI2
6360           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6361           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6362   "!TARGET_P8_VECTOR"
6363   "#"
6364   "reload_completed && !TARGET_P8_VECTOR"
6365   [(const_int 0)]
6367   rs6000_split_logical (operands, XOR, true, false, false);
6368   DONE;
6370   [(set_attr "type" "integer")
6371    (set (attr "length")
6372         (if_then_else
6373          (match_test "TARGET_POWERPC64")
6374          (const_string "8")
6375          (const_string "16")))])
6377 ;; 128-bit one's complement
6378 (define_insn_and_split "*one_cmpl<mode>3_internal"
6379   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6380         (not:BOOL_128
6381           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6382   ""
6384   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6385     return "xxlnor %x0,%x1,%x1";
6387   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6388     return "vnor %0,%1,%1";
6390   return "#";
6392   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6393   [(const_int 0)]
6395   rs6000_split_logical (operands, NOT, false, false, false);
6396   DONE;
6398   [(set (attr "type")
6399       (if_then_else
6400         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6401         (const_string "veclogical")
6402         (const_string "integer")))
6403    (set (attr "length")
6404       (if_then_else
6405         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6406         (const_string "4")
6407         (if_then_else
6408          (match_test "TARGET_POWERPC64")
6409          (const_string "8")
6410          (const_string "16"))))])
6413 ;; Now define ways of moving data around.
6415 ;; Set up a register with a value from the GOT table
6417 (define_expand "movsi_got"
6418   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6419         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6420                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6421   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6422   "
6424   if (GET_CODE (operands[1]) == CONST)
6425     {
6426       rtx offset = const0_rtx;
6427       HOST_WIDE_INT value;
6429       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6430       value = INTVAL (offset);
6431       if (value != 0)
6432         {
6433           rtx tmp = (!can_create_pseudo_p ()
6434                      ? operands[0]
6435                      : gen_reg_rtx (Pmode));
6436           emit_insn (gen_movsi_got (tmp, operands[1]));
6437           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6438           DONE;
6439         }
6440     }
6442   operands[2] = rs6000_got_register (operands[1]);
6445 (define_insn "*movsi_got_internal"
6446   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6447         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6448                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6449                    UNSPEC_MOVSI_GOT))]
6450   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6451   "lwz %0,%a1@got(%2)"
6452   [(set_attr "type" "load")])
6454 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6455 ;; didn't get allocated to a hard register.
6456 (define_split
6457   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6458         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6459                     (match_operand:SI 2 "memory_operand" "")]
6460                    UNSPEC_MOVSI_GOT))]
6461   "DEFAULT_ABI == ABI_V4
6462     && flag_pic == 1
6463     && (reload_in_progress || reload_completed)"
6464   [(set (match_dup 0) (match_dup 2))
6465    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6466                                  UNSPEC_MOVSI_GOT))]
6467   "")
6469 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6470 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6471 ;; and this is even supposed to be faster, but it is simpler not to get
6472 ;; integers in the TOC.
6473 (define_insn "movsi_low"
6474   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6475         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6476                            (match_operand 2 "" ""))))]
6477   "TARGET_MACHO && ! TARGET_64BIT"
6478   "lwz %0,lo16(%2)(%1)"
6479   [(set_attr "type" "load")
6480    (set_attr "length" "4")])
6482 (define_insn "*movsi_internal1"
6483   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6484         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6485   "!TARGET_SINGLE_FPU &&
6486    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6487   "@
6488    mr %0,%1
6489    la %0,%a1
6490    lwz%U1%X1 %0,%1
6491    stw%U0%X0 %1,%0
6492    li %0,%1
6493    lis %0,%v1
6494    #
6495    mf%1 %0
6496    mt%0 %1
6497    mt%0 %1
6498    nop"
6499   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6500    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6502 (define_insn "*movsi_internal1_single"
6503   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6504         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6505   "TARGET_SINGLE_FPU &&
6506    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6507   "@
6508    mr %0,%1
6509    la %0,%a1
6510    lwz%U1%X1 %0,%1
6511    stw%U0%X0 %1,%0
6512    li %0,%1
6513    lis %0,%v1
6514    #
6515    mf%1 %0
6516    mt%0 %1
6517    mt%0 %1
6518    nop
6519    stfs%U0%X0 %1,%0
6520    lfs%U1%X1 %0,%1"
6521   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6522    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6524 ;; Split a load of a large constant into the appropriate two-insn
6525 ;; sequence.
6527 (define_split
6528   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6529         (match_operand:SI 1 "const_int_operand" ""))]
6530   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6531    && (INTVAL (operands[1]) & 0xffff) != 0"
6532   [(set (match_dup 0)
6533         (match_dup 2))
6534    (set (match_dup 0)
6535         (ior:SI (match_dup 0)
6536                 (match_dup 3)))]
6537   "
6539   if (rs6000_emit_set_const (operands[0], operands[1]))
6540     DONE;
6541   else
6542     FAIL;
6545 (define_insn "*mov<mode>_internal2"
6546   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6547         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6548                     (const_int 0)))
6549    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6550   ""
6551   "@
6552    cmp<wd>i %2,%0,0
6553    mr. %0,%1
6554    #"
6555   [(set_attr "type" "cmp,logical,cmp")
6556    (set_attr "dot" "yes")
6557    (set_attr "length" "4,4,8")])
6559 (define_split
6560   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6561         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6562                     (const_int 0)))
6563    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6564   "reload_completed"
6565   [(set (match_dup 0) (match_dup 1))
6566    (set (match_dup 2)
6567         (compare:CC (match_dup 0)
6568                     (const_int 0)))]
6569   "")
6571 (define_insn "*movhi_internal"
6572   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6573         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6574   "gpc_reg_operand (operands[0], HImode)
6575    || gpc_reg_operand (operands[1], HImode)"
6576   "@
6577    mr %0,%1
6578    lhz%U1%X1 %0,%1
6579    sth%U0%X0 %1,%0
6580    li %0,%w1
6581    mf%1 %0
6582    mt%0 %1
6583    nop"
6584   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6586 (define_expand "mov<mode>"
6587   [(set (match_operand:INT 0 "general_operand" "")
6588         (match_operand:INT 1 "any_operand" ""))]
6589   ""
6590   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6592 (define_insn "*movqi_internal"
6593   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6594         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6595   "gpc_reg_operand (operands[0], QImode)
6596    || gpc_reg_operand (operands[1], QImode)"
6597   "@
6598    mr %0,%1
6599    lbz%U1%X1 %0,%1
6600    stb%U0%X0 %1,%0
6601    li %0,%1
6602    mf%1 %0
6603    mt%0 %1
6604    nop"
6605   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6607 ;; Here is how to move condition codes around.  When we store CC data in
6608 ;; an integer register or memory, we store just the high-order 4 bits.
6609 ;; This lets us not shift in the most common case of CR0.
6610 (define_expand "movcc"
6611   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6612         (match_operand:CC 1 "nonimmediate_operand" ""))]
6613   ""
6614   "")
6616 (define_insn "*movcc_internal1"
6617   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6618         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6619   "register_operand (operands[0], CCmode)
6620    || register_operand (operands[1], CCmode)"
6621   "@
6622    mcrf %0,%1
6623    mtcrf 128,%1
6624    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6625    crxor %0,%0,%0
6626    mfcr %0%Q1
6627    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6628    mr %0,%1
6629    li %0,%1
6630    mf%1 %0
6631    mt%0 %1
6632    lwz%U1%X1 %0,%1
6633    stw%U0%X0 %1,%0"
6634   [(set (attr "type")
6635      (cond [(eq_attr "alternative" "0,3")
6636                 (const_string "cr_logical")
6637             (eq_attr "alternative" "1,2")
6638                 (const_string "mtcr")
6639             (eq_attr "alternative" "6,7")
6640                 (const_string "integer")
6641             (eq_attr "alternative" "8")
6642                 (const_string "mfjmpr")
6643             (eq_attr "alternative" "9")
6644                 (const_string "mtjmpr")
6645             (eq_attr "alternative" "10")
6646                 (const_string "load")
6647             (eq_attr "alternative" "11")
6648                 (const_string "store")
6649             (match_test "TARGET_MFCRF")
6650                 (const_string "mfcrf")
6651            ]
6652         (const_string "mfcr")))
6653    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6655 ;; For floating-point, we normally deal with the floating-point registers
6656 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6657 ;; can produce floating-point values in fixed-point registers.  Unless the
6658 ;; value is a simple constant or already in memory, we deal with this by
6659 ;; allocating memory and copying the value explicitly via that memory location.
6661 ;; Move 32-bit binary/decimal floating point
6662 (define_expand "mov<mode>"
6663   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6664         (match_operand:FMOVE32 1 "any_operand" ""))]
6665   "<fmove_ok>"
6666   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6668 (define_split
6669   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6670         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6671   "reload_completed
6672    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6673        || (GET_CODE (operands[0]) == SUBREG
6674            && GET_CODE (SUBREG_REG (operands[0])) == REG
6675            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6676   [(set (match_dup 2) (match_dup 3))]
6677   "
6679   long l;
6681   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6683   if (! TARGET_POWERPC64)
6684     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6685   else
6686     operands[2] = gen_lowpart (SImode, operands[0]);
6688   operands[3] = gen_int_mode (l, SImode);
6691 (define_insn "mov<mode>_hardfloat"
6692   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6693         (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,<zero_fp>,<zero_fp>,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6694   "(gpc_reg_operand (operands[0], <MODE>mode)
6695    || gpc_reg_operand (operands[1], <MODE>mode))
6696    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6697   "@
6698    mr %0,%1
6699    lwz%U1%X1 %0,%1
6700    stw%U0%X0 %1,%0
6701    fmr %0,%1
6702    xscpsgndp %x0,%x1,%x1
6703    xxlxor %x0,%x0,%x0
6704    li %0,0
6705    <f32_li>
6706    <f32_li2>
6707    <f32_si>
6708    <f32_si2>
6709    <f32_lv>
6710    <f32_sv>
6711    mtvsrwz %x0,%1
6712    mfvsrwz %0,%x1
6713    mt%0 %1
6714    mf%1 %0
6715    nop"
6716   [(set_attr "type" "*,load,store,fpsimple,fpsimple,veclogical,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
6717    (set_attr "length" "4")])
6719 (define_insn "*mov<mode>_softfloat"
6720   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6721         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6722   "(gpc_reg_operand (operands[0], <MODE>mode)
6723    || gpc_reg_operand (operands[1], <MODE>mode))
6724    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6725   "@
6726    mr %0,%1
6727    mt%0 %1
6728    mf%1 %0
6729    lwz%U1%X1 %0,%1
6730    stw%U0%X0 %1,%0
6731    li %0,%1
6732    lis %0,%v1
6733    #
6734    #
6735    nop"
6736   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6737    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6740 ;; Move 64-bit binary/decimal floating point
6741 (define_expand "mov<mode>"
6742   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6743         (match_operand:FMOVE64 1 "any_operand" ""))]
6744   ""
6745   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6747 (define_split
6748   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6749         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6750   "! TARGET_POWERPC64 && reload_completed
6751    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6752        || (GET_CODE (operands[0]) == SUBREG
6753            && GET_CODE (SUBREG_REG (operands[0])) == REG
6754            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6755   [(set (match_dup 2) (match_dup 4))
6756    (set (match_dup 3) (match_dup 1))]
6757   "
6759   int endian = (WORDS_BIG_ENDIAN == 0);
6760   HOST_WIDE_INT value = INTVAL (operands[1]);
6762   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6763   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6764   operands[4] = GEN_INT (value >> 32);
6765   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6768 (define_split
6769   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6770         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6771   "! TARGET_POWERPC64 && reload_completed
6772    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6773        || (GET_CODE (operands[0]) == SUBREG
6774            && GET_CODE (SUBREG_REG (operands[0])) == REG
6775            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6776   [(set (match_dup 2) (match_dup 4))
6777    (set (match_dup 3) (match_dup 5))]
6778   "
6780   int endian = (WORDS_BIG_ENDIAN == 0);
6781   long l[2];
6783   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6785   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6786   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6787   operands[4] = gen_int_mode (l[endian], SImode);
6788   operands[5] = gen_int_mode (l[1 - endian], SImode);
6791 (define_split
6792   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6793         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6794   "TARGET_POWERPC64 && reload_completed
6795    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6796        || (GET_CODE (operands[0]) == SUBREG
6797            && GET_CODE (SUBREG_REG (operands[0])) == REG
6798            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6799   [(set (match_dup 2) (match_dup 3))]
6800   "
6802   int endian = (WORDS_BIG_ENDIAN == 0);
6803   long l[2];
6804   HOST_WIDE_INT val;
6806   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6808   operands[2] = gen_lowpart (DImode, operands[0]);
6809   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6810   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6811          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6813   operands[3] = gen_int_mode (val, DImode);
6816 ;; Don't have reload use general registers to load a constant.  It is
6817 ;; less efficient than loading the constant into an FP register, since
6818 ;; it will probably be used there.
6820 ;; The move constraints are ordered to prefer floating point registers before
6821 ;; general purpose registers to avoid doing a store and a load to get the value
6822 ;; into a floating point register when it is needed for a floating point
6823 ;; operation.  Prefer traditional floating point registers over VSX registers,
6824 ;; since the D-form version of the memory instructions does not need a GPR for
6825 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6826 ;; registers.
6828 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6829 ;; except for 0.0 which can be created on VSX with an xor instruction.
6831 (define_insn "*mov<mode>_hardfloat32"
6832   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6833         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6834   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6835    && (gpc_reg_operand (operands[0], <MODE>mode)
6836        || gpc_reg_operand (operands[1], <MODE>mode))"
6837   "@
6838    stfd%U0%X0 %1,%0
6839    lfd%U1%X1 %0,%1
6840    fmr %0,%1
6841    lxsd%U1x %x0,%y1
6842    stxsd%U0x %x1,%y0
6843    lxsd %0,%1
6844    stxsd %1,%0
6845    xxlor %x0,%x1,%x1
6846    xxlxor %x0,%x0,%x0
6847    #
6848    #
6849    #
6850    #"
6851   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6852    (set_attr "size" "64")
6853    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6855 (define_insn "*mov<mode>_softfloat32"
6856   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6857         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6858   "! TARGET_POWERPC64 
6859    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6860        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6861        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6862    && (gpc_reg_operand (operands[0], <MODE>mode)
6863        || gpc_reg_operand (operands[1], <MODE>mode))"
6864   "#"
6865   [(set_attr "type" "store,load,two,*,*,*")
6866    (set_attr "length" "8,8,8,8,12,16")])
6868 ; ld/std require word-aligned displacements -> 'Y' constraint.
6869 ; List Y->r and r->Y before r->r for reload.
6870 (define_insn "*mov<mode>_hardfloat64"
6871   [(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>")
6872         (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"))]
6873   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6874    && (gpc_reg_operand (operands[0], <MODE>mode)
6875        || gpc_reg_operand (operands[1], <MODE>mode))"
6876   "@
6877    stfd%U0%X0 %1,%0
6878    lfd%U1%X1 %0,%1
6879    fmr %0,%1
6880    lxsd %0,%1
6881    stxsd %1,%0
6882    lxsd%U1x %x0,%y1
6883    stxsd%U0x %x1,%y0
6884    xxlor %x0,%x1,%x1
6885    xxlxor %x0,%x0,%x0
6886    li %0,0
6887    std%U0%X0 %1,%0
6888    ld%U1%X1 %0,%1
6889    mr %0,%1
6890    mt%0 %1
6891    mf%1 %0
6892    nop
6893    mftgpr %0,%1
6894    mffgpr %0,%1
6895    mfvsrd %0,%x1
6896    mtvsrd %x0,%1"
6897   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6898    (set_attr "size" "64")
6899    (set_attr "length" "4")])
6901 (define_insn "*mov<mode>_softfloat64"
6902   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6903         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6904   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6905    && (gpc_reg_operand (operands[0], <MODE>mode)
6906        || gpc_reg_operand (operands[1], <MODE>mode))"
6907   "@
6908    std%U0%X0 %1,%0
6909    ld%U1%X1 %0,%1
6910    mr %0,%1
6911    mt%0 %1
6912    mf%1 %0
6913    #
6914    #
6915    #
6916    nop"
6917   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6918    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6920 (define_expand "mov<mode>"
6921   [(set (match_operand:FMOVE128 0 "general_operand" "")
6922         (match_operand:FMOVE128 1 "any_operand" ""))]
6923   ""
6924   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6926 ;; It's important to list Y->r and r->Y before r->r because otherwise
6927 ;; reload, given m->r, will try to pick r->r and reload it, which
6928 ;; doesn't make progress.
6930 ;; We can't split little endian direct moves of TDmode, because the words are
6931 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6932 ;; problematical.  Don't allow direct move for this case.
6934 (define_insn_and_split "*mov<mode>_64bit_dm"
6935   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6936         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6937   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6938    && FLOAT128_2REG_P (<MODE>mode)
6939    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6940    && (gpc_reg_operand (operands[0], <MODE>mode)
6941        || gpc_reg_operand (operands[1], <MODE>mode))"
6942   "#"
6943   "&& reload_completed"
6944   [(pc)]
6945 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6946   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6948 (define_insn_and_split "*movtd_64bit_nodm"
6949   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6950         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6951   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6952    && (gpc_reg_operand (operands[0], TDmode)
6953        || gpc_reg_operand (operands[1], TDmode))"
6954   "#"
6955   "&& reload_completed"
6956   [(pc)]
6957 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6958   [(set_attr "length" "8,8,8,12,12,8")])
6960 (define_insn_and_split "*mov<mode>_32bit"
6961   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
6962         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
6963   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6964    && (FLOAT128_2REG_P (<MODE>mode)
6965        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6966        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6967    && (gpc_reg_operand (operands[0], <MODE>mode)
6968        || gpc_reg_operand (operands[1], <MODE>mode))"
6969   "#"
6970   "&& reload_completed"
6971   [(pc)]
6972 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6973   [(set_attr "length" "8,8,8,8,20,20,16")])
6975 (define_insn_and_split "*mov<mode>_softfloat"
6976   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6977         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6978   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6979    && (gpc_reg_operand (operands[0], <MODE>mode)
6980        || gpc_reg_operand (operands[1], <MODE>mode))"
6981   "#"
6982   "&& reload_completed"
6983   [(pc)]
6984 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6985   [(set_attr "length" "20,20,16")])
6987 (define_expand "extenddf<mode>2"
6988   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6989         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6990   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6991    && TARGET_LONG_DOUBLE_128"
6993   if (FLOAT128_IEEE_P (<MODE>mode))
6994     rs6000_expand_float128_convert (operands[0], operands[1], false);
6995   else if (TARGET_E500_DOUBLE)
6996     {
6997       gcc_assert (<MODE>mode == TFmode);
6998       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6999     }
7000   else if (TARGET_VSX)
7001     {
7002       if (<MODE>mode == TFmode)
7003         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7004       else if (<MODE>mode == IFmode)
7005         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7006       else
7007         gcc_unreachable ();
7008     }
7009    else
7010     {
7011       rtx zero = gen_reg_rtx (DFmode);
7012       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7014       if (<MODE>mode == TFmode)
7015         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7016       else if (<MODE>mode == IFmode)
7017         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7018       else
7019         gcc_unreachable ();
7020     }
7021   DONE;
7024 ;; Allow memory operands for the source to be created by the combiner.
7025 (define_insn_and_split "extenddf<mode>2_fprs"
7026   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7027         (float_extend:IBM128
7028          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7029    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7030   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7031    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7032   "#"
7033   "&& reload_completed"
7034   [(set (match_dup 3) (match_dup 1))
7035    (set (match_dup 4) (match_dup 2))]
7037   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7038   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7040   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7041   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7044 (define_insn_and_split "extenddf<mode>2_vsx"
7045   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7046         (float_extend:IBM128
7047          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7048   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7049   "#"
7050   "&& reload_completed"
7051   [(set (match_dup 2) (match_dup 1))
7052    (set (match_dup 3) (match_dup 4))]
7054   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7055   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7057   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7058   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7059   operands[4] = CONST0_RTX (DFmode);
7062 (define_expand "extendsf<mode>2"
7063   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7064         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7065   "TARGET_HARD_FLOAT
7066    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7067    && TARGET_LONG_DOUBLE_128"
7069   if (FLOAT128_IEEE_P (<MODE>mode))
7070     rs6000_expand_float128_convert (operands[0], operands[1], false);
7071   else
7072     {
7073       rtx tmp = gen_reg_rtx (DFmode);
7074       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7075       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7076     }
7077   DONE;
7080 (define_expand "trunc<mode>df2"
7081   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7082         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7083   "TARGET_HARD_FLOAT
7084    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7085    && TARGET_LONG_DOUBLE_128"
7087   if (FLOAT128_IEEE_P (<MODE>mode))
7088     {
7089       rs6000_expand_float128_convert (operands[0], operands[1], false);
7090       DONE;
7091     }
7094 (define_insn_and_split "trunc<mode>df2_internal1"
7095   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7096         (float_truncate:DF
7097          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7098   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7099    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7100   "@
7101    #
7102    fmr %0,%1"
7103   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7104   [(const_int 0)]
7106   emit_note (NOTE_INSN_DELETED);
7107   DONE;
7109   [(set_attr "type" "fpsimple")])
7111 (define_insn "trunc<mode>df2_internal2"
7112   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7113         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7114   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7115    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7116   "fadd %0,%1,%L1"
7117   [(set_attr "type" "fp")
7118    (set_attr "fp_type" "fp_addsub_d")])
7120 (define_expand "trunc<mode>sf2"
7121   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7122         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7123   "TARGET_HARD_FLOAT
7124    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7125    && TARGET_LONG_DOUBLE_128"
7127   if (FLOAT128_IEEE_P (<MODE>mode))
7128     rs6000_expand_float128_convert (operands[0], operands[1], false);
7129   else if (TARGET_E500_DOUBLE)
7130     {
7131       gcc_assert (<MODE>mode == TFmode);
7132       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7133     }
7134   else if (<MODE>mode == TFmode)
7135     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7136   else if (<MODE>mode == IFmode)
7137     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7138   else
7139     gcc_unreachable ();
7140   DONE;
7143 (define_insn_and_split "trunc<mode>sf2_fprs"
7144   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7145         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7146    (clobber (match_scratch:DF 2 "=d"))]
7147   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7148    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7149   "#"
7150   "&& reload_completed"
7151   [(set (match_dup 2)
7152         (float_truncate:DF (match_dup 1)))
7153    (set (match_dup 0)
7154         (float_truncate:SF (match_dup 2)))]
7155   "")
7157 (define_expand "floatsi<mode>2"
7158   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7159         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7160   "TARGET_HARD_FLOAT
7161    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7162    && TARGET_LONG_DOUBLE_128"
7164   if (FLOAT128_IEEE_P (<MODE>mode))
7165     rs6000_expand_float128_convert (operands[0], operands[1], false);
7166   else
7167     {
7168       rtx tmp = gen_reg_rtx (DFmode);
7169       expand_float (tmp, operands[1], false);
7170       if (<MODE>mode == TFmode)
7171         emit_insn (gen_extenddftf2 (operands[0], tmp));
7172       else if (<MODE>mode == IFmode)
7173         emit_insn (gen_extenddfif2 (operands[0], tmp));
7174       else
7175         gcc_unreachable ();
7176     }
7177   DONE;
7180 ; fadd, but rounding towards zero.
7181 ; This is probably not the optimal code sequence.
7182 (define_insn "fix_trunc_helper<mode>"
7183   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7184         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7185                    UNSPEC_FIX_TRUNC_TF))
7186    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7187   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7188    && FLOAT128_IBM_P (<MODE>mode)"
7189   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7190   [(set_attr "type" "fp")
7191    (set_attr "length" "20")])
7193 (define_expand "fix_trunc<mode>si2"
7194   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7195         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7196   "TARGET_HARD_FLOAT
7197    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7199   if (FLOAT128_IEEE_P (<MODE>mode))
7200     rs6000_expand_float128_convert (operands[0], operands[1], false);
7201   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7202     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7203   else if (<MODE>mode == TFmode)
7204     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7205   else if (<MODE>mode == IFmode)
7206     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7207   else
7208     gcc_unreachable ();
7209   DONE;
7212 (define_expand "fix_trunc<mode>si2_fprs"
7213   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7214                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7215               (clobber (match_dup 2))
7216               (clobber (match_dup 3))
7217               (clobber (match_dup 4))
7218               (clobber (match_dup 5))])]
7219   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7221   operands[2] = gen_reg_rtx (DFmode);
7222   operands[3] = gen_reg_rtx (DFmode);
7223   operands[4] = gen_reg_rtx (DImode);
7224   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7227 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7228   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7229         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7230    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7231    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7232    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7233    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7234   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7235   "#"
7236   ""
7237   [(pc)]
7239   rtx lowword;
7240   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7241                                          operands[3]));
7243   gcc_assert (MEM_P (operands[5]));
7244   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7246   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7247   emit_move_insn (operands[5], operands[4]);
7248   emit_move_insn (operands[0], lowword);
7249   DONE;
7252 (define_expand "fix_trunc<mode>di2"
7253   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7254         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7255   "TARGET_FLOAT128"
7257   rs6000_expand_float128_convert (operands[0], operands[1], false);
7258   DONE;
7261 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7262   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7263         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7264   "TARGET_FLOAT128"
7266   rs6000_expand_float128_convert (operands[0], operands[1], true);
7267   DONE;
7270 (define_expand "floatdi<mode>2"
7271   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7272         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7273   "TARGET_FLOAT128"
7275   rs6000_expand_float128_convert (operands[0], operands[1], false);
7276   DONE;
7279 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7280   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7281         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7282   "TARGET_FLOAT128"
7284   rs6000_expand_float128_convert (operands[0], operands[1], true);
7285   DONE;
7288 (define_expand "neg<mode>2"
7289   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7290         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7291   "FLOAT128_IEEE_P (<MODE>mode)
7292    || (FLOAT128_IBM_P (<MODE>mode)
7293        && TARGET_HARD_FLOAT
7294        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7295   "
7297   if (FLOAT128_IEEE_P (<MODE>mode))
7298     {
7299       if (TARGET_FLOAT128_HW)
7300         {
7301           if (<MODE>mode == TFmode)
7302             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7303           else if (<MODE>mode == KFmode)
7304             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7305           else
7306             gcc_unreachable ();
7307         }
7308       else if (TARGET_FLOAT128)
7309         {
7310           if (<MODE>mode == TFmode)
7311             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7312           else if (<MODE>mode == KFmode)
7313             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7314           else
7315             gcc_unreachable ();
7316         }
7317       else
7318         {
7319           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7320           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7321                                                 <MODE>mode, 1,
7322                                                 operands[1], <MODE>mode);
7324           if (target && !rtx_equal_p (target, operands[0]))
7325             emit_move_insn (operands[0], target);
7326         }
7327       DONE;
7328     }
7331 (define_insn "neg<mode>2_internal"
7332   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7333         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7334   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7335   "*
7337   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7338     return \"fneg %L0,%L1\;fneg %0,%1\";
7339   else
7340     return \"fneg %0,%1\;fneg %L0,%L1\";
7342   [(set_attr "type" "fpsimple")
7343    (set_attr "length" "8")])
7345 (define_expand "abs<mode>2"
7346   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7347         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7348   "FLOAT128_IEEE_P (<MODE>mode)
7349    || (FLOAT128_IBM_P (<MODE>mode)
7350        && TARGET_HARD_FLOAT
7351        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7352   "
7354   rtx label;
7356   if (FLOAT128_IEEE_P (<MODE>mode))
7357     {
7358       if (TARGET_FLOAT128_HW)
7359         {
7360           if (<MODE>mode == TFmode)
7361             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7362           else if (<MODE>mode == KFmode)
7363             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7364           else
7365             FAIL;
7366           DONE;
7367         }
7368       else if (TARGET_FLOAT128)
7369         {
7370           if (<MODE>mode == TFmode)
7371             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7372           else if (<MODE>mode == KFmode)
7373             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7374           else
7375             FAIL;
7376           DONE;
7377         }
7378       else
7379         FAIL;
7380     }
7382   label = gen_label_rtx ();
7383   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7384     {
7385       if (flag_finite_math_only && !flag_trapping_math)
7386         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7387       else
7388         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7389     }
7390   else if (<MODE>mode == TFmode)
7391     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7392   else if (<MODE>mode == TFmode)
7393     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7394   else
7395     FAIL;
7396   emit_label (label);
7397   DONE;
7400 (define_expand "abs<mode>2_internal"
7401   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7402         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7403    (set (match_dup 3) (match_dup 5))
7404    (set (match_dup 5) (abs:DF (match_dup 5)))
7405    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7406    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7407                            (label_ref (match_operand 2 "" ""))
7408                            (pc)))
7409    (set (match_dup 6) (neg:DF (match_dup 6)))]
7410   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7411    && TARGET_LONG_DOUBLE_128"
7412   "
7414   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7415   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7416   operands[3] = gen_reg_rtx (DFmode);
7417   operands[4] = gen_reg_rtx (CCFPmode);
7418   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7419   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7423 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7424 ;; register
7426 (define_expand "ieee_128bit_negative_zero"
7427   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7428   "TARGET_FLOAT128"
7430   rtvec v = rtvec_alloc (16);
7431   int i, high;
7433   for (i = 0; i < 16; i++)
7434     RTVEC_ELT (v, i) = const0_rtx;
7436   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7437   RTVEC_ELT (v, high) = GEN_INT (0x80);
7439   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7440   DONE;
7443 ;; IEEE 128-bit negate
7445 ;; We have 2 insns here for negate and absolute value.  The first uses
7446 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7447 ;; insns, and second insn after the first split pass loads up the bit to
7448 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7449 ;; neg/abs to create the constant just once.
7451 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7452   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7453         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7454    (clobber (match_scratch:V16QI 2 "=v"))]
7455   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7456   "#"
7457   "&& 1"
7458   [(parallel [(set (match_dup 0)
7459                    (neg:IEEE128 (match_dup 1)))
7460               (use (match_dup 2))])]
7462   if (GET_CODE (operands[2]) == SCRATCH)
7463     operands[2] = gen_reg_rtx (V16QImode);
7465   operands[3] = gen_reg_rtx (V16QImode);
7466   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7468   [(set_attr "length" "8")
7469    (set_attr "type" "vecsimple")])
7471 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7472   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7473         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7474    (use (match_operand:V16QI 2 "register_operand" "v"))]
7475   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7476   "xxlxor %x0,%x1,%x2"
7477   [(set_attr "type" "veclogical")])
7479 ;; IEEE 128-bit absolute value
7480 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7481   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7482         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7483    (clobber (match_scratch:V16QI 2 "=v"))]
7484   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7485   "#"
7486   "&& 1"
7487   [(parallel [(set (match_dup 0)
7488                    (abs:IEEE128 (match_dup 1)))
7489               (use (match_dup 2))])]
7491   if (GET_CODE (operands[2]) == SCRATCH)
7492     operands[2] = gen_reg_rtx (V16QImode);
7494   operands[3] = gen_reg_rtx (V16QImode);
7495   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7497   [(set_attr "length" "8")
7498    (set_attr "type" "vecsimple")])
7500 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7501   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7502         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7503    (use (match_operand:V16QI 2 "register_operand" "v"))]
7504   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7505   "xxlandc %x0,%x1,%x2"
7506   [(set_attr "type" "veclogical")])
7508 ;; IEEE 128-bit negative absolute value
7509 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7510   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7511         (neg:IEEE128
7512          (abs:IEEE128
7513           (match_operand:IEEE128 1 "register_operand" "wa"))))
7514    (clobber (match_scratch:V16QI 2 "=v"))]
7515   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7516   "#"
7517   "&& 1"
7518   [(parallel [(set (match_dup 0)
7519                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7520               (use (match_dup 2))])]
7522   if (GET_CODE (operands[2]) == SCRATCH)
7523     operands[2] = gen_reg_rtx (V16QImode);
7525   operands[3] = gen_reg_rtx (V16QImode);
7526   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7528   [(set_attr "length" "8")
7529    (set_attr "type" "vecsimple")])
7531 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7532   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7533         (neg:IEEE128
7534          (abs:IEEE128
7535           (match_operand:IEEE128 1 "register_operand" "wa"))))
7536    (use (match_operand:V16QI 2 "register_operand" "v"))]
7537   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7538   "xxlor %x0,%x1,%x2"
7539   [(set_attr "type" "veclogical")])
7541 ;; Float128 conversion functions.  These expand to library function calls.
7542 ;; We use expand to convert from IBM double double to IEEE 128-bit
7543 ;; and trunc for the opposite.
7544 (define_expand "extendiftf2"
7545   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7546         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7547   "TARGET_FLOAT128"
7549   rs6000_expand_float128_convert (operands[0], operands[1], false);
7550   DONE;
7553 (define_expand "extendifkf2"
7554   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7555         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7556   "TARGET_FLOAT128"
7558   rs6000_expand_float128_convert (operands[0], operands[1], false);
7559   DONE;
7562 (define_expand "extendtfkf2"
7563   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7564         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7565   "TARGET_FLOAT128"
7567   rs6000_expand_float128_convert (operands[0], operands[1], false);
7568   DONE;
7571 (define_expand "trunciftf2"
7572   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7573         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7574   "TARGET_FLOAT128"
7576   rs6000_expand_float128_convert (operands[0], operands[1], false);
7577   DONE;
7580 (define_expand "truncifkf2"
7581   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7582         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7583   "TARGET_FLOAT128"
7585   rs6000_expand_float128_convert (operands[0], operands[1], false);
7586   DONE;
7589 (define_expand "trunckftf2"
7590   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7591         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7592   "TARGET_FLOAT128"
7594   rs6000_expand_float128_convert (operands[0], operands[1], false);
7595   DONE;
7598 (define_expand "trunctfif2"
7599   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7600         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7601   "TARGET_FLOAT128"
7603   rs6000_expand_float128_convert (operands[0], operands[1], false);
7604   DONE;
7608 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7609 ;; must have 3 arguments, and scratch register constraint must be a single
7610 ;; constraint.
7612 ;; Reload patterns to support gpr load/store with misaligned mem.
7613 ;; and multiple gpr load/store at offset >= 0xfffc
7614 (define_expand "reload_<mode>_store"
7615   [(parallel [(match_operand 0 "memory_operand" "=m")
7616               (match_operand 1 "gpc_reg_operand" "r")
7617               (match_operand:GPR 2 "register_operand" "=&b")])]
7618   ""
7620   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7621   DONE;
7624 (define_expand "reload_<mode>_load"
7625   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7626               (match_operand 1 "memory_operand" "m")
7627               (match_operand:GPR 2 "register_operand" "=b")])]
7628   ""
7630   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7631   DONE;
7635 ;; Reload patterns for various types using the vector registers.  We may need
7636 ;; an additional base register to convert the reg+offset addressing to reg+reg
7637 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7638 ;; index register for gpr registers.
7639 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7640   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7641               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7642               (match_operand:P 2 "register_operand" "=b")])]
7643   "<P:tptrsize>"
7645   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7646   DONE;
7649 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7650   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7651               (match_operand:RELOAD 1 "memory_operand" "m")
7652               (match_operand:P 2 "register_operand" "=b")])]
7653   "<P:tptrsize>"
7655   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7656   DONE;
7660 ;; Reload sometimes tries to move the address to a GPR, and can generate
7661 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7662 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7664 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7665   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7666         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7667                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7668                (const_int -16)))]
7669   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7670   "#"
7671   "&& reload_completed"
7672   [(set (match_dup 0)
7673         (plus:P (match_dup 1)
7674                 (match_dup 2)))
7675    (set (match_dup 0)
7676         (and:P (match_dup 0)
7677                (const_int -16)))])
7679 ;; Power8 merge instructions to allow direct move to/from floating point
7680 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7681 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7682 ;; value, since it is allocated in reload and not all of the flow information
7683 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7684 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7685 ;; schedule other instructions between the two instructions.
7687 (define_insn "p8_fmrgow_<mode>"
7688   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7689         (unspec:FMOVE64X [
7690                 (match_operand:DF 1 "register_operand" "d")
7691                 (match_operand:DF 2 "register_operand" "d")]
7692                          UNSPEC_P8V_FMRGOW))]
7693   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7694   "fmrgow %0,%1,%2"
7695   [(set_attr "type" "fpsimple")])
7697 (define_insn "p8_mtvsrwz"
7698   [(set (match_operand:DF 0 "register_operand" "=d")
7699         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7700                    UNSPEC_P8V_MTVSRWZ))]
7701   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7702   "mtvsrwz %x0,%1"
7703   [(set_attr "type" "mftgpr")])
7705 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7706   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7707         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7708                          UNSPEC_P8V_RELOAD_FROM_GPR))
7709    (clobber (match_operand:IF 2 "register_operand" "=d"))]
7710   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7711   "#"
7712   "&& reload_completed"
7713   [(const_int 0)]
7715   rtx dest = operands[0];
7716   rtx src = operands[1];
7717   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7718   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7719   rtx gpr_hi_reg = gen_highpart (SImode, src);
7720   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7722   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7723   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7724   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7725   DONE;
7727   [(set_attr "length" "12")
7728    (set_attr "type" "three")])
7730 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7731 (define_insn "p8_mtvsrd_df"
7732   [(set (match_operand:DF 0 "register_operand" "=wa")
7733         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7734                    UNSPEC_P8V_MTVSRD))]
7735   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7736   "mtvsrd %x0,%1"
7737   [(set_attr "type" "mftgpr")])
7739 (define_insn "p8_xxpermdi_<mode>"
7740   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7741         (unspec:FMOVE128_GPR [
7742                 (match_operand:DF 1 "register_operand" "wa")
7743                 (match_operand:DF 2 "register_operand" "wa")]
7744                 UNSPEC_P8V_XXPERMDI))]
7745   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7746   "xxpermdi %x0,%x1,%x2,0"
7747   [(set_attr "type" "vecperm")])
7749 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7750   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7751         (unspec:FMOVE128_GPR
7752          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7753          UNSPEC_P8V_RELOAD_FROM_GPR))
7754    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7755   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7756   "#"
7757   "&& reload_completed"
7758   [(const_int 0)]
7760   rtx dest = operands[0];
7761   rtx src = operands[1];
7762   /* You might think that we could use op0 as one temp and a DF clobber
7763      as op2, but you'd be wrong.  Secondary reload move patterns don't
7764      check for overlap of the clobber and the destination.  */
7765   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7766   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7767   rtx gpr_hi_reg = gen_highpart (DImode, src);
7768   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7770   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7771   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7772   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7773   DONE;
7775   [(set_attr "length" "12")
7776    (set_attr "type" "three")])
7778 (define_split
7779   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7780         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7781   "reload_completed
7782    && (int_reg_operand (operands[0], <MODE>mode)
7783        || int_reg_operand (operands[1], <MODE>mode))
7784    && (!TARGET_DIRECT_MOVE_128
7785        || (!vsx_register_operand (operands[0], <MODE>mode)
7786            && !vsx_register_operand (operands[1], <MODE>mode)))"
7787   [(pc)]
7788 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7790 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7791 ;; type is stored internally as double precision in the VSX registers, we have
7792 ;; to convert it from the vector format.
7793 (define_insn "p8_mtvsrd_sf"
7794   [(set (match_operand:SF 0 "register_operand" "=wa")
7795         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7796                    UNSPEC_P8V_MTVSRD))]
7797   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7798   "mtvsrd %x0,%1"
7799   [(set_attr "type" "mftgpr")])
7801 (define_insn_and_split "reload_vsx_from_gprsf"
7802   [(set (match_operand:SF 0 "register_operand" "=wa")
7803         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7804                    UNSPEC_P8V_RELOAD_FROM_GPR))
7805    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7806   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7807   "#"
7808   "&& reload_completed"
7809   [(const_int 0)]
7811   rtx op0 = operands[0];
7812   rtx op1 = operands[1];
7813   rtx op2 = operands[2];
7814   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7816   /* Move SF value to upper 32-bits for xscvspdpn.  */
7817   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7818   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7819   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7820   DONE;
7822   [(set_attr "length" "8")
7823    (set_attr "type" "two")])
7825 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7826 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7827 ;; and then doing a move of that.
7828 (define_insn "p8_mfvsrd_3_<mode>"
7829   [(set (match_operand:DF 0 "register_operand" "=r")
7830         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7831                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7832   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7833   "mfvsrd %0,%x1"
7834   [(set_attr "type" "mftgpr")])
7836 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7837   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7838         (unspec:FMOVE128_GPR
7839          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7840          UNSPEC_P8V_RELOAD_FROM_VSX))
7841    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7842   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7843   "#"
7844   "&& reload_completed"
7845   [(const_int 0)]
7847   rtx dest = operands[0];
7848   rtx src = operands[1];
7849   rtx tmp = operands[2];
7850   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7851   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7853   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7854   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7855   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7856   DONE;
7858   [(set_attr "length" "12")
7859    (set_attr "type" "three")])
7861 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7862 ;; type is stored internally as double precision, we have to convert it to the
7863 ;; vector format.
7865 (define_insn_and_split "reload_gpr_from_vsxsf"
7866   [(set (match_operand:SF 0 "register_operand" "=r")
7867         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7868                    UNSPEC_P8V_RELOAD_FROM_VSX))
7869    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7870   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7871   "#"
7872   "&& reload_completed"
7873   [(const_int 0)]
7875   rtx op0 = operands[0];
7876   rtx op1 = operands[1];
7877   rtx op2 = operands[2];
7878   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7880   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7881   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7882   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7883   DONE;
7885   [(set_attr "length" "12")
7886    (set_attr "type" "three")])
7888 (define_insn "p8_mfvsrd_4_disf"
7889   [(set (match_operand:DI 0 "register_operand" "=r")
7890         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7891                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7892   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7893   "mfvsrd %0,%x1"
7894   [(set_attr "type" "mftgpr")])
7897 ;; Next come the multi-word integer load and store and the load and store
7898 ;; multiple insns.
7900 ;; List r->r after r->Y, otherwise reload will try to reload a
7901 ;; non-offsettable address by using r->r which won't make progress.
7902 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7903 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7905 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
7906 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
7907 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
7908 ;;        AVX const  
7910 (define_insn "*movdi_internal32"
7911   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
7912          "=Y,        r,         r,         ?m,        ?*d,        ?*d,
7913           r,         ?wY,       ?Z,        ?*wb,      ?*wv,       ?wi,
7914           ?wo,       ?wo,       ?wv,       ?wi,       ?wi,        ?wv,
7915           ?wv")
7917         (match_operand:DI 1 "input_operand"
7918           "r,        Y,         r,         d,         m,          d,
7919            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
7920            Oj,       wM,        OjwM,      Oj,        wM,         wS,
7921            wB"))]
7923   "! TARGET_POWERPC64
7924    && (gpc_reg_operand (operands[0], DImode)
7925        || gpc_reg_operand (operands[1], DImode))"
7926   "@
7927    #
7928    #
7929    #
7930    stfd%U0%X0 %1,%0
7931    lfd%U1%X1 %0,%1
7932    fmr %0,%1
7933    #
7934    stxsd %1,%0
7935    stxsdx %x1,%y0
7936    lxsd %0,%1
7937    lxsdx %x0,%y1
7938    xxlor %x0,%x1,%x1
7939    xxspltib %x0,0
7940    xxspltib %x0,255
7941    vspltisw %0,%1
7942    xxlxor %x0,%x0,%x0
7943    xxlorc %x0,%x0,%x0
7944    #
7945    #"
7946   [(set_attr "type"
7947                "store,     load,      *,         fpstore,    fpload,     fpsimple,
7948                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
7949                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
7950                 vecsimple")
7951    (set_attr "size" "64")])
7953 (define_split
7954   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7955         (match_operand:DI 1 "const_int_operand" ""))]
7956   "! TARGET_POWERPC64 && reload_completed
7957    && gpr_or_gpr_p (operands[0], operands[1])
7958    && !direct_move_p (operands[0], operands[1])"
7959   [(set (match_dup 2) (match_dup 4))
7960    (set (match_dup 3) (match_dup 1))]
7961   "
7963   HOST_WIDE_INT value = INTVAL (operands[1]);
7964   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7965                                        DImode);
7966   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7967                                        DImode);
7968   operands[4] = GEN_INT (value >> 32);
7969   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7972 (define_split
7973   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7974         (match_operand:DIFD 1 "input_operand" ""))]
7975   "reload_completed && !TARGET_POWERPC64
7976    && gpr_or_gpr_p (operands[0], operands[1])
7977    && !direct_move_p (operands[0], operands[1])"
7978   [(pc)]
7979 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7981 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
7982 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
7983 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
7984 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
7985 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
7986 (define_insn "*movdi_internal64"
7987   [(set (match_operand:DI 0 "nonimmediate_operand"
7988                "=Y,        r,         r,         r,         r,          r,
7989                 ?m,        ?*d,       ?*d,       ?wY,       ?Z,         ?*wb,
7990                 ?*wv,      ?wi,       ?wo,       ?wo,       ?wv,        ?wi,
7991                 ?wi,       ?wv,       ?wv,       r,         *h,         *h,
7992                 ?*r,       ?*wg,      ?*r,       ?*wj")
7994         (match_operand:DI 1 "input_operand"
7995                 "r,        Y,         r,         I,         L,          nF,
7996                  d,        m,         d,         wb,        wv,         wY,
7997                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
7998                  wM,       wS,        wB,        *h,        r,          0,
7999                  wg,       r,         wj,        r"))]
8001   "TARGET_POWERPC64
8002    && (gpc_reg_operand (operands[0], DImode)
8003        || gpc_reg_operand (operands[1], DImode))"
8004   "@
8005    std%U0%X0 %1,%0
8006    ld%U1%X1 %0,%1
8007    mr %0,%1
8008    li %0,%1
8009    lis %0,%v1
8010    #
8011    stfd%U0%X0 %1,%0
8012    lfd%U1%X1 %0,%1
8013    fmr %0,%1
8014    stxsd %1,%0
8015    stxsdx %x1,%y0
8016    lxsd %0,%1
8017    lxsdx %x0,%y1
8018    xxlor %x0,%x1,%x1
8019    xxspltib %x0,0
8020    xxspltib %x0,255
8021    vspltisw %0,%1
8022    xxlxor %x0,%x0,%x0
8023    xxlorc %x0,%x0,%x0
8024    #
8025    #
8026    mf%1 %0
8027    mt%0 %1
8028    nop
8029    mftgpr %0,%1
8030    mffgpr %0,%1
8031    mfvsrd %0,%x1
8032    mtvsrd %x0,%1"
8033   [(set_attr "type"
8034                "store,      load,       *,         *,         *,         *,
8035                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8036                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8037                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8038                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8040    (set_attr "size" "64")
8041    (set_attr "length"
8042                "4,         4,         4,         4,         4,          20,
8043                 4,         4,         4,         4,         4,          4,
8044                 4,         4,         4,         4,         4,          8,
8045                 8,         4,         4,         4,         4,          4,
8046                 4,         4,         4,         4")])
8048 ; Some DImode loads are best done as a load of -1 followed by a mask
8049 ; instruction.
8050 (define_split
8051   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8052         (match_operand:DI 1 "const_int_operand"))]
8053   "TARGET_POWERPC64
8054    && num_insns_constant (operands[1], DImode) > 1
8055    && rs6000_is_valid_and_mask (operands[1], DImode)"
8056   [(set (match_dup 0)
8057         (const_int -1))
8058    (set (match_dup 0)
8059         (and:DI (match_dup 0)
8060                 (match_dup 1)))]
8061   "")
8063 ;; Split a load of a large constant into the appropriate five-instruction
8064 ;; sequence.  Handle anything in a constant number of insns.
8065 ;; When non-easy constants can go in the TOC, this should use
8066 ;; easy_fp_constant predicate.
8067 (define_split
8068   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8069         (match_operand:DI 1 "const_int_operand" ""))]
8070   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8071   [(set (match_dup 0) (match_dup 2))
8072    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8073   "
8075   if (rs6000_emit_set_const (operands[0], operands[1]))
8076     DONE;
8077   else
8078     FAIL;
8081 (define_split
8082   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8083         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8084   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8085   [(set (match_dup 0) (match_dup 2))
8086    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8087   "
8089   if (rs6000_emit_set_const (operands[0], operands[1]))
8090     DONE;
8091   else
8092     FAIL;
8095 (define_split
8096   [(set (match_operand:DI 0 "altivec_register_operand" "")
8097         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8098   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8099   [(const_int 0)]
8101   rtx op0 = operands[0];
8102   rtx op1 = operands[1];
8103   int r = REGNO (op0);
8104   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8106   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8107   if (op1 != const0_rtx && op1 != constm1_rtx)
8108     {
8109       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8110       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8111     }
8112   DONE;
8115 (define_split
8116   [(set (match_operand:DI 0 "altivec_register_operand" "")
8117         (match_operand:DI 1 "xxspltib_constant_split" ""))]
8118   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8119   [(const_int 0)]
8121   rtx op0 = operands[0];
8122   rtx op1 = operands[1];
8123   int r = REGNO (op0);
8124   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8126   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8127   emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8128   DONE;
8132 ;; TImode/PTImode is similar, except that we usually want to compute the
8133 ;; address into a register and use lsi/stsi (the exception is during reload).
8135 (define_insn "*mov<mode>_string"
8136   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8137         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8138   "! TARGET_POWERPC64
8139    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8140    && (gpc_reg_operand (operands[0], <MODE>mode)
8141        || gpc_reg_operand (operands[1], <MODE>mode))"
8142   "*
8144   switch (which_alternative)
8145     {
8146     default:
8147       gcc_unreachable ();
8148     case 0:
8149       if (TARGET_STRING)
8150         return \"stswi %1,%P0,16\";
8151     case 1:
8152       return \"#\";
8153     case 2:
8154       /* If the address is not used in the output, we can use lsi.  Otherwise,
8155          fall through to generating four loads.  */
8156       if (TARGET_STRING
8157           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8158         return \"lswi %0,%P1,16\";
8159       /* ... fall through ...  */
8160     case 3:
8161     case 4:
8162     case 5:
8163       return \"#\";
8164     }
8166   [(set_attr "type" "store,store,load,load,*,*")
8167    (set_attr "update" "yes")
8168    (set_attr "indexed" "yes")
8169    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8170                                           (const_string "always")
8171                                           (const_string "conditional")))])
8173 (define_insn "*mov<mode>_ppc64"
8174   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8175         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8176   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8177    && (gpc_reg_operand (operands[0], <MODE>mode)
8178        || gpc_reg_operand (operands[1], <MODE>mode)))"
8180   return rs6000_output_move_128bit (operands);
8182   [(set_attr "type" "store,store,load,load,*,*")
8183    (set_attr "length" "8")])
8185 (define_split
8186   [(set (match_operand:TI2 0 "int_reg_operand" "")
8187         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8188   "TARGET_POWERPC64
8189    && (VECTOR_MEM_NONE_P (<MODE>mode)
8190        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8191   [(set (match_dup 2) (match_dup 4))
8192    (set (match_dup 3) (match_dup 5))]
8193   "
8195   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8196                                        <MODE>mode);
8197   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8198                                        <MODE>mode);
8199   if (CONST_WIDE_INT_P (operands[1]))
8200     {
8201       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8202       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8203     }
8204   else if (CONST_INT_P (operands[1]))
8205     {
8206       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8207       operands[5] = operands[1];
8208     }
8209   else
8210     FAIL;
8213 (define_split
8214   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8215         (match_operand:TI2 1 "input_operand" ""))]
8216   "reload_completed
8217    && gpr_or_gpr_p (operands[0], operands[1])
8218    && !direct_move_p (operands[0], operands[1])
8219    && !quad_load_store_p (operands[0], operands[1])"
8220   [(pc)]
8221 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8223 (define_expand "load_multiple"
8224   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8225                           (match_operand:SI 1 "" ""))
8226                      (use (match_operand:SI 2 "" ""))])]
8227   "TARGET_STRING && !TARGET_POWERPC64"
8228   "
8230   int regno;
8231   int count;
8232   rtx op1;
8233   int i;
8235   /* Support only loading a constant number of fixed-point registers from
8236      memory and only bother with this if more than two; the machine
8237      doesn't support more than eight.  */
8238   if (GET_CODE (operands[2]) != CONST_INT
8239       || INTVAL (operands[2]) <= 2
8240       || INTVAL (operands[2]) > 8
8241       || GET_CODE (operands[1]) != MEM
8242       || GET_CODE (operands[0]) != REG
8243       || REGNO (operands[0]) >= 32)
8244     FAIL;
8246   count = INTVAL (operands[2]);
8247   regno = REGNO (operands[0]);
8249   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8250   op1 = replace_equiv_address (operands[1],
8251                                force_reg (SImode, XEXP (operands[1], 0)));
8253   for (i = 0; i < count; i++)
8254     XVECEXP (operands[3], 0, i)
8255       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8256                      adjust_address_nv (op1, SImode, i * 4));
8259 (define_insn "*ldmsi8"
8260   [(match_parallel 0 "load_multiple_operation"
8261     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8262           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8263      (set (match_operand:SI 3 "gpc_reg_operand" "")
8264           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8265      (set (match_operand:SI 4 "gpc_reg_operand" "")
8266           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8267      (set (match_operand:SI 5 "gpc_reg_operand" "")
8268           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8269      (set (match_operand:SI 6 "gpc_reg_operand" "")
8270           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8271      (set (match_operand:SI 7 "gpc_reg_operand" "")
8272           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8273      (set (match_operand:SI 8 "gpc_reg_operand" "")
8274           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8275      (set (match_operand:SI 9 "gpc_reg_operand" "")
8276           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8277   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8278   "*
8279 { return rs6000_output_load_multiple (operands); }"
8280   [(set_attr "type" "load")
8281    (set_attr "update" "yes")
8282    (set_attr "indexed" "yes")
8283    (set_attr "length" "32")])
8285 (define_insn "*ldmsi7"
8286   [(match_parallel 0 "load_multiple_operation"
8287     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8288           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8289      (set (match_operand:SI 3 "gpc_reg_operand" "")
8290           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8291      (set (match_operand:SI 4 "gpc_reg_operand" "")
8292           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8293      (set (match_operand:SI 5 "gpc_reg_operand" "")
8294           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8295      (set (match_operand:SI 6 "gpc_reg_operand" "")
8296           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8297      (set (match_operand:SI 7 "gpc_reg_operand" "")
8298           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8299      (set (match_operand:SI 8 "gpc_reg_operand" "")
8300           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8301   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8302   "*
8303 { return rs6000_output_load_multiple (operands); }"
8304   [(set_attr "type" "load")
8305    (set_attr "update" "yes")
8306    (set_attr "indexed" "yes")
8307    (set_attr "length" "32")])
8309 (define_insn "*ldmsi6"
8310   [(match_parallel 0 "load_multiple_operation"
8311     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8312           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8313      (set (match_operand:SI 3 "gpc_reg_operand" "")
8314           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8315      (set (match_operand:SI 4 "gpc_reg_operand" "")
8316           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8317      (set (match_operand:SI 5 "gpc_reg_operand" "")
8318           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8319      (set (match_operand:SI 6 "gpc_reg_operand" "")
8320           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8321      (set (match_operand:SI 7 "gpc_reg_operand" "")
8322           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8323   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8324   "*
8325 { return rs6000_output_load_multiple (operands); }"
8326   [(set_attr "type" "load")
8327    (set_attr "update" "yes")
8328    (set_attr "indexed" "yes")
8329    (set_attr "length" "32")])
8331 (define_insn "*ldmsi5"
8332   [(match_parallel 0 "load_multiple_operation"
8333     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8334           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8335      (set (match_operand:SI 3 "gpc_reg_operand" "")
8336           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8337      (set (match_operand:SI 4 "gpc_reg_operand" "")
8338           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8339      (set (match_operand:SI 5 "gpc_reg_operand" "")
8340           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8341      (set (match_operand:SI 6 "gpc_reg_operand" "")
8342           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8343   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8344   "*
8345 { return rs6000_output_load_multiple (operands); }"
8346   [(set_attr "type" "load")
8347    (set_attr "update" "yes")
8348    (set_attr "indexed" "yes")
8349    (set_attr "length" "32")])
8351 (define_insn "*ldmsi4"
8352   [(match_parallel 0 "load_multiple_operation"
8353     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8354           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8355      (set (match_operand:SI 3 "gpc_reg_operand" "")
8356           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8357      (set (match_operand:SI 4 "gpc_reg_operand" "")
8358           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8359      (set (match_operand:SI 5 "gpc_reg_operand" "")
8360           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8361   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8362   "*
8363 { return rs6000_output_load_multiple (operands); }"
8364   [(set_attr "type" "load")
8365    (set_attr "update" "yes")
8366    (set_attr "indexed" "yes")
8367    (set_attr "length" "32")])
8369 (define_insn "*ldmsi3"
8370   [(match_parallel 0 "load_multiple_operation"
8371     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8372           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8373      (set (match_operand:SI 3 "gpc_reg_operand" "")
8374           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8375      (set (match_operand:SI 4 "gpc_reg_operand" "")
8376           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8377   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8378   "*
8379 { return rs6000_output_load_multiple (operands); }"
8380   [(set_attr "type" "load")
8381    (set_attr "update" "yes")
8382    (set_attr "indexed" "yes")
8383    (set_attr "length" "32")])
8385 (define_expand "store_multiple"
8386   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8387                           (match_operand:SI 1 "" ""))
8388                      (clobber (scratch:SI))
8389                      (use (match_operand:SI 2 "" ""))])]
8390   "TARGET_STRING && !TARGET_POWERPC64"
8391   "
8393   int regno;
8394   int count;
8395   rtx to;
8396   rtx op0;
8397   int i;
8399   /* Support only storing a constant number of fixed-point registers to
8400      memory and only bother with this if more than two; the machine
8401      doesn't support more than eight.  */
8402   if (GET_CODE (operands[2]) != CONST_INT
8403       || INTVAL (operands[2]) <= 2
8404       || INTVAL (operands[2]) > 8
8405       || GET_CODE (operands[0]) != MEM
8406       || GET_CODE (operands[1]) != REG
8407       || REGNO (operands[1]) >= 32)
8408     FAIL;
8410   count = INTVAL (operands[2]);
8411   regno = REGNO (operands[1]);
8413   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8414   to = force_reg (SImode, XEXP (operands[0], 0));
8415   op0 = replace_equiv_address (operands[0], to);
8417   XVECEXP (operands[3], 0, 0)
8418     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8419   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8420                                                  gen_rtx_SCRATCH (SImode));
8422   for (i = 1; i < count; i++)
8423     XVECEXP (operands[3], 0, i + 1)
8424       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8425                      gen_rtx_REG (SImode, regno + i));
8428 (define_insn "*stmsi8"
8429   [(match_parallel 0 "store_multiple_operation"
8430     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8431           (match_operand:SI 2 "gpc_reg_operand" "r"))
8432      (clobber (match_scratch:SI 3 "=X"))
8433      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8434           (match_operand:SI 4 "gpc_reg_operand" "r"))
8435      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8436           (match_operand:SI 5 "gpc_reg_operand" "r"))
8437      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8438           (match_operand:SI 6 "gpc_reg_operand" "r"))
8439      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8440           (match_operand:SI 7 "gpc_reg_operand" "r"))
8441      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8442           (match_operand:SI 8 "gpc_reg_operand" "r"))
8443      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8444           (match_operand:SI 9 "gpc_reg_operand" "r"))
8445      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8446           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8447   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8448   "stswi %2,%1,%O0"
8449   [(set_attr "type" "store")
8450    (set_attr "update" "yes")
8451    (set_attr "indexed" "yes")
8452    (set_attr "cell_micro" "always")])
8454 (define_insn "*stmsi7"
8455   [(match_parallel 0 "store_multiple_operation"
8456     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8457           (match_operand:SI 2 "gpc_reg_operand" "r"))
8458      (clobber (match_scratch:SI 3 "=X"))
8459      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8460           (match_operand:SI 4 "gpc_reg_operand" "r"))
8461      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8462           (match_operand:SI 5 "gpc_reg_operand" "r"))
8463      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8464           (match_operand:SI 6 "gpc_reg_operand" "r"))
8465      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8466           (match_operand:SI 7 "gpc_reg_operand" "r"))
8467      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8468           (match_operand:SI 8 "gpc_reg_operand" "r"))
8469      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8470           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8471   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8472   "stswi %2,%1,%O0"
8473   [(set_attr "type" "store")
8474    (set_attr "update" "yes")
8475    (set_attr "indexed" "yes")
8476    (set_attr "cell_micro" "always")])
8478 (define_insn "*stmsi6"
8479   [(match_parallel 0 "store_multiple_operation"
8480     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8481           (match_operand:SI 2 "gpc_reg_operand" "r"))
8482      (clobber (match_scratch:SI 3 "=X"))
8483      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8484           (match_operand:SI 4 "gpc_reg_operand" "r"))
8485      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8486           (match_operand:SI 5 "gpc_reg_operand" "r"))
8487      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8488           (match_operand:SI 6 "gpc_reg_operand" "r"))
8489      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8490           (match_operand:SI 7 "gpc_reg_operand" "r"))
8491      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8492           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8493   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8494   "stswi %2,%1,%O0"
8495   [(set_attr "type" "store")
8496    (set_attr "update" "yes")
8497    (set_attr "indexed" "yes")
8498    (set_attr "cell_micro" "always")])
8500 (define_insn "*stmsi5"
8501   [(match_parallel 0 "store_multiple_operation"
8502     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8503           (match_operand:SI 2 "gpc_reg_operand" "r"))
8504      (clobber (match_scratch:SI 3 "=X"))
8505      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8506           (match_operand:SI 4 "gpc_reg_operand" "r"))
8507      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8508           (match_operand:SI 5 "gpc_reg_operand" "r"))
8509      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8510           (match_operand:SI 6 "gpc_reg_operand" "r"))
8511      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8512           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8513   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8514   "stswi %2,%1,%O0"
8515   [(set_attr "type" "store")
8516    (set_attr "update" "yes")
8517    (set_attr "indexed" "yes")
8518    (set_attr "cell_micro" "always")])
8520 (define_insn "*stmsi4"
8521   [(match_parallel 0 "store_multiple_operation"
8522     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8523           (match_operand:SI 2 "gpc_reg_operand" "r"))
8524      (clobber (match_scratch:SI 3 "=X"))
8525      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8526           (match_operand:SI 4 "gpc_reg_operand" "r"))
8527      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8528           (match_operand:SI 5 "gpc_reg_operand" "r"))
8529      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8530           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8531   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8532   "stswi %2,%1,%O0"
8533   [(set_attr "type" "store")
8534    (set_attr "update" "yes")
8535    (set_attr "indexed" "yes")
8536    (set_attr "cell_micro" "always")])
8538 (define_insn "*stmsi3"
8539   [(match_parallel 0 "store_multiple_operation"
8540     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8541           (match_operand:SI 2 "gpc_reg_operand" "r"))
8542      (clobber (match_scratch:SI 3 "=X"))
8543      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8544           (match_operand:SI 4 "gpc_reg_operand" "r"))
8545      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8546           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8547   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8548   "stswi %2,%1,%O0"
8549   [(set_attr "type" "store")
8550    (set_attr "update" "yes")
8551    (set_attr "indexed" "yes")
8552    (set_attr "cell_micro" "always")])
8554 (define_expand "setmemsi"
8555   [(parallel [(set (match_operand:BLK 0 "" "")
8556                    (match_operand 2 "const_int_operand" ""))
8557               (use (match_operand:SI 1 "" ""))
8558               (use (match_operand:SI 3 "" ""))])]
8559   ""
8560   "
8562   /* If value to set is not zero, use the library routine.  */
8563   if (operands[2] != const0_rtx)
8564     FAIL;
8566   if (expand_block_clear (operands))
8567     DONE;
8568   else
8569     FAIL;
8572 ;; String/block move insn.
8573 ;; Argument 0 is the destination
8574 ;; Argument 1 is the source
8575 ;; Argument 2 is the length
8576 ;; Argument 3 is the alignment
8578 (define_expand "movmemsi"
8579   [(parallel [(set (match_operand:BLK 0 "" "")
8580                    (match_operand:BLK 1 "" ""))
8581               (use (match_operand:SI 2 "" ""))
8582               (use (match_operand:SI 3 "" ""))])]
8583   ""
8584   "
8586   if (expand_block_move (operands))
8587     DONE;
8588   else
8589     FAIL;
8592 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8593 ;; register allocator doesn't have a clue about allocating 8 word registers.
8594 ;; rD/rS = r5 is preferred, efficient form.
8595 (define_expand "movmemsi_8reg"
8596   [(parallel [(set (match_operand 0 "" "")
8597                    (match_operand 1 "" ""))
8598               (use (match_operand 2 "" ""))
8599               (use (match_operand 3 "" ""))
8600               (clobber (reg:SI  5))
8601               (clobber (reg:SI  6))
8602               (clobber (reg:SI  7))
8603               (clobber (reg:SI  8))
8604               (clobber (reg:SI  9))
8605               (clobber (reg:SI 10))
8606               (clobber (reg:SI 11))
8607               (clobber (reg:SI 12))
8608               (clobber (match_scratch:SI 4 ""))])]
8609   "TARGET_STRING"
8610   "")
8612 (define_insn ""
8613   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8614         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8615    (use (match_operand:SI 2 "immediate_operand" "i"))
8616    (use (match_operand:SI 3 "immediate_operand" "i"))
8617    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8618    (clobber (reg:SI  6))
8619    (clobber (reg:SI  7))
8620    (clobber (reg:SI  8))
8621    (clobber (reg:SI  9))
8622    (clobber (reg:SI 10))
8623    (clobber (reg:SI 11))
8624    (clobber (reg:SI 12))
8625    (clobber (match_scratch:SI 5 "=X"))]
8626   "TARGET_STRING
8627    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8628        || INTVAL (operands[2]) == 0)
8629    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8630    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8631    && REGNO (operands[4]) == 5"
8632   "lswi %4,%1,%2\;stswi %4,%0,%2"
8633   [(set_attr "type" "store")
8634    (set_attr "update" "yes")
8635    (set_attr "indexed" "yes")
8636    (set_attr "cell_micro" "always")
8637    (set_attr "length" "8")])
8639 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8640 ;; register allocator doesn't have a clue about allocating 6 word registers.
8641 ;; rD/rS = r5 is preferred, efficient form.
8642 (define_expand "movmemsi_6reg"
8643   [(parallel [(set (match_operand 0 "" "")
8644                    (match_operand 1 "" ""))
8645               (use (match_operand 2 "" ""))
8646               (use (match_operand 3 "" ""))
8647               (clobber (reg:SI  5))
8648               (clobber (reg:SI  6))
8649               (clobber (reg:SI  7))
8650               (clobber (reg:SI  8))
8651               (clobber (reg:SI  9))
8652               (clobber (reg:SI 10))
8653               (clobber (match_scratch:SI 4 ""))])]
8654   "TARGET_STRING"
8655   "")
8657 (define_insn ""
8658   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8659         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8660    (use (match_operand:SI 2 "immediate_operand" "i"))
8661    (use (match_operand:SI 3 "immediate_operand" "i"))
8662    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8663    (clobber (reg:SI  6))
8664    (clobber (reg:SI  7))
8665    (clobber (reg:SI  8))
8666    (clobber (reg:SI  9))
8667    (clobber (reg:SI 10))
8668    (clobber (match_scratch:SI 5 "=X"))]
8669   "TARGET_STRING
8670    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8671    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8672    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8673    && REGNO (operands[4]) == 5"
8674   "lswi %4,%1,%2\;stswi %4,%0,%2"
8675   [(set_attr "type" "store")
8676    (set_attr "update" "yes")
8677    (set_attr "indexed" "yes")
8678    (set_attr "cell_micro" "always")
8679    (set_attr "length" "8")])
8681 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8682 ;; problems with TImode.
8683 ;; rD/rS = r5 is preferred, efficient form.
8684 (define_expand "movmemsi_4reg"
8685   [(parallel [(set (match_operand 0 "" "")
8686                    (match_operand 1 "" ""))
8687               (use (match_operand 2 "" ""))
8688               (use (match_operand 3 "" ""))
8689               (clobber (reg:SI 5))
8690               (clobber (reg:SI 6))
8691               (clobber (reg:SI 7))
8692               (clobber (reg:SI 8))
8693               (clobber (match_scratch:SI 4 ""))])]
8694   "TARGET_STRING"
8695   "")
8697 (define_insn ""
8698   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8699         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8700    (use (match_operand:SI 2 "immediate_operand" "i"))
8701    (use (match_operand:SI 3 "immediate_operand" "i"))
8702    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8703    (clobber (reg:SI 6))
8704    (clobber (reg:SI 7))
8705    (clobber (reg:SI 8))
8706    (clobber (match_scratch:SI 5 "=X"))]
8707   "TARGET_STRING
8708    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8709    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8710    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8711    && REGNO (operands[4]) == 5"
8712   "lswi %4,%1,%2\;stswi %4,%0,%2"
8713   [(set_attr "type" "store")
8714    (set_attr "update" "yes")
8715    (set_attr "indexed" "yes")
8716    (set_attr "cell_micro" "always")
8717    (set_attr "length" "8")])
8719 ;; Move up to 8 bytes at a time.
8720 (define_expand "movmemsi_2reg"
8721   [(parallel [(set (match_operand 0 "" "")
8722                    (match_operand 1 "" ""))
8723               (use (match_operand 2 "" ""))
8724               (use (match_operand 3 "" ""))
8725               (clobber (match_scratch:DI 4 ""))
8726               (clobber (match_scratch:SI 5 ""))])]
8727   "TARGET_STRING && ! TARGET_POWERPC64"
8728   "")
8730 (define_insn ""
8731   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8732         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8733    (use (match_operand:SI 2 "immediate_operand" "i"))
8734    (use (match_operand:SI 3 "immediate_operand" "i"))
8735    (clobber (match_scratch:DI 4 "=&r"))
8736    (clobber (match_scratch:SI 5 "=X"))]
8737   "TARGET_STRING && ! TARGET_POWERPC64
8738    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8739   "lswi %4,%1,%2\;stswi %4,%0,%2"
8740   [(set_attr "type" "store")
8741    (set_attr "update" "yes")
8742    (set_attr "indexed" "yes")
8743    (set_attr "cell_micro" "always")
8744    (set_attr "length" "8")])
8746 ;; Move up to 4 bytes at a time.
8747 (define_expand "movmemsi_1reg"
8748   [(parallel [(set (match_operand 0 "" "")
8749                    (match_operand 1 "" ""))
8750               (use (match_operand 2 "" ""))
8751               (use (match_operand 3 "" ""))
8752               (clobber (match_scratch:SI 4 ""))
8753               (clobber (match_scratch:SI 5 ""))])]
8754   "TARGET_STRING"
8755   "")
8757 (define_insn ""
8758   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8759         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8760    (use (match_operand:SI 2 "immediate_operand" "i"))
8761    (use (match_operand:SI 3 "immediate_operand" "i"))
8762    (clobber (match_scratch:SI 4 "=&r"))
8763    (clobber (match_scratch:SI 5 "=X"))]
8764   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8765   "lswi %4,%1,%2\;stswi %4,%0,%2"
8766   [(set_attr "type" "store")
8767    (set_attr "update" "yes")
8768    (set_attr "indexed" "yes")
8769    (set_attr "cell_micro" "always")
8770    (set_attr "length" "8")])
8772 ;; Define insns that do load or store with update.  Some of these we can
8773 ;; get by using pre-decrement or pre-increment, but the hardware can also
8774 ;; do cases where the increment is not the size of the object.
8776 ;; In all these cases, we use operands 0 and 1 for the register being
8777 ;; incremented because those are the operands that local-alloc will
8778 ;; tie and these are the pair most likely to be tieable (and the ones
8779 ;; that will benefit the most).
8781 (define_insn "*movdi_update1"
8782   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8783         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8784                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8785    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8786         (plus:DI (match_dup 1) (match_dup 2)))]
8787   "TARGET_POWERPC64 && TARGET_UPDATE
8788    && (!avoiding_indexed_address_p (DImode)
8789        || !gpc_reg_operand (operands[2], DImode))"
8790   "@
8791    ldux %3,%0,%2
8792    ldu %3,%2(%0)"
8793   [(set_attr "type" "load")
8794    (set_attr "update" "yes")
8795    (set_attr "indexed" "yes,no")])
8797 (define_insn "movdi_<mode>_update"
8798   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8799                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8800         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8801    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8802         (plus:P (match_dup 1) (match_dup 2)))]
8803   "TARGET_POWERPC64 && TARGET_UPDATE
8804    && (!avoiding_indexed_address_p (Pmode)
8805        || !gpc_reg_operand (operands[2], Pmode)
8806        || (REG_P (operands[0])
8807            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8808   "@
8809    stdux %3,%0,%2
8810    stdu %3,%2(%0)"
8811   [(set_attr "type" "store")
8812    (set_attr "update" "yes")
8813    (set_attr "indexed" "yes,no")])
8815 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8816 ;; needed for stack allocation, even if the user passes -mno-update.
8817 (define_insn "movdi_<mode>_update_stack"
8818   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8819                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8820         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8821    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8822         (plus:P (match_dup 1) (match_dup 2)))]
8823   "TARGET_POWERPC64"
8824   "@
8825    stdux %3,%0,%2
8826    stdu %3,%2(%0)"
8827   [(set_attr "type" "store")
8828    (set_attr "update" "yes")
8829    (set_attr "indexed" "yes,no")])
8831 (define_insn "*movsi_update1"
8832   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8833         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8834                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8835    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8836         (plus:SI (match_dup 1) (match_dup 2)))]
8837   "TARGET_UPDATE
8838    && (!avoiding_indexed_address_p (SImode)
8839        || !gpc_reg_operand (operands[2], SImode))"
8840   "@
8841    lwzux %3,%0,%2
8842    lwzu %3,%2(%0)"
8843   [(set_attr "type" "load")
8844    (set_attr "update" "yes")
8845    (set_attr "indexed" "yes,no")])
8847 (define_insn "*movsi_update2"
8848   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8849         (sign_extend:DI
8850          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8851                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8852    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8853         (plus:DI (match_dup 1) (match_dup 2)))]
8854   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8855    && !avoiding_indexed_address_p (DImode)"
8856   "lwaux %3,%0,%2"
8857   [(set_attr "type" "load")
8858    (set_attr "sign_extend" "yes")
8859    (set_attr "update" "yes")
8860    (set_attr "indexed" "yes")])
8862 (define_insn "movsi_update"
8863   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8864                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8865         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8866    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8867         (plus:SI (match_dup 1) (match_dup 2)))]
8868   "TARGET_UPDATE
8869    && (!avoiding_indexed_address_p (SImode)
8870        || !gpc_reg_operand (operands[2], SImode)
8871        || (REG_P (operands[0])
8872            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8873   "@
8874    stwux %3,%0,%2
8875    stwu %3,%2(%0)"
8876   [(set_attr "type" "store")
8877    (set_attr "update" "yes")
8878    (set_attr "indexed" "yes,no")])
8880 ;; This is an unconditional pattern; needed for stack allocation, even
8881 ;; if the user passes -mno-update.
8882 (define_insn "movsi_update_stack"
8883   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8884                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8885         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8886    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8887         (plus:SI (match_dup 1) (match_dup 2)))]
8888   ""
8889   "@
8890    stwux %3,%0,%2
8891    stwu %3,%2(%0)"
8892   [(set_attr "type" "store")
8893    (set_attr "update" "yes")
8894    (set_attr "indexed" "yes,no")])
8896 (define_insn "*movhi_update1"
8897   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8898         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8899                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8900    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8901         (plus:SI (match_dup 1) (match_dup 2)))]
8902   "TARGET_UPDATE
8903    && (!avoiding_indexed_address_p (SImode)
8904        || !gpc_reg_operand (operands[2], SImode))"
8905   "@
8906    lhzux %3,%0,%2
8907    lhzu %3,%2(%0)"
8908   [(set_attr "type" "load")
8909    (set_attr "update" "yes")
8910    (set_attr "indexed" "yes,no")])
8912 (define_insn "*movhi_update2"
8913   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8914         (zero_extend:SI
8915          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8916                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8917    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8918         (plus:SI (match_dup 1) (match_dup 2)))]
8919   "TARGET_UPDATE
8920    && (!avoiding_indexed_address_p (SImode)
8921        || !gpc_reg_operand (operands[2], SImode))"
8922   "@
8923    lhzux %3,%0,%2
8924    lhzu %3,%2(%0)"
8925   [(set_attr "type" "load")
8926    (set_attr "update" "yes")
8927    (set_attr "indexed" "yes,no")])
8929 (define_insn "*movhi_update3"
8930   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8931         (sign_extend:SI
8932          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8933                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8934    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8935         (plus:SI (match_dup 1) (match_dup 2)))]
8936   "TARGET_UPDATE && rs6000_gen_cell_microcode
8937    && (!avoiding_indexed_address_p (SImode)
8938        || !gpc_reg_operand (operands[2], SImode))"
8939   "@
8940    lhaux %3,%0,%2
8941    lhau %3,%2(%0)"
8942   [(set_attr "type" "load")
8943    (set_attr "sign_extend" "yes")
8944    (set_attr "update" "yes")
8945    (set_attr "indexed" "yes,no")])
8947 (define_insn "*movhi_update4"
8948   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8949                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8950         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8951    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8952         (plus:SI (match_dup 1) (match_dup 2)))]
8953   "TARGET_UPDATE
8954    && (!avoiding_indexed_address_p (SImode)
8955        || !gpc_reg_operand (operands[2], SImode))"
8956   "@
8957    sthux %3,%0,%2
8958    sthu %3,%2(%0)"
8959   [(set_attr "type" "store")
8960    (set_attr "update" "yes")
8961    (set_attr "indexed" "yes,no")])
8963 (define_insn "*movqi_update1"
8964   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8965         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8966                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8967    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8968         (plus:SI (match_dup 1) (match_dup 2)))]
8969   "TARGET_UPDATE
8970    && (!avoiding_indexed_address_p (SImode)
8971        || !gpc_reg_operand (operands[2], SImode))"
8972   "@
8973    lbzux %3,%0,%2
8974    lbzu %3,%2(%0)"
8975   [(set_attr "type" "load")
8976    (set_attr "update" "yes")
8977    (set_attr "indexed" "yes,no")])
8979 (define_insn "*movqi_update2"
8980   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8981         (zero_extend:SI
8982          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8983                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8984    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8985         (plus:SI (match_dup 1) (match_dup 2)))]
8986   "TARGET_UPDATE
8987    && (!avoiding_indexed_address_p (SImode)
8988        || !gpc_reg_operand (operands[2], SImode))"
8989   "@
8990    lbzux %3,%0,%2
8991    lbzu %3,%2(%0)"
8992   [(set_attr "type" "load")
8993    (set_attr "update" "yes")
8994    (set_attr "indexed" "yes,no")])
8996 (define_insn "*movqi_update3"
8997   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8998                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8999         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9000    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9001         (plus:SI (match_dup 1) (match_dup 2)))]
9002   "TARGET_UPDATE
9003    && (!avoiding_indexed_address_p (SImode)
9004        || !gpc_reg_operand (operands[2], SImode))"
9005   "@
9006    stbux %3,%0,%2
9007    stbu %3,%2(%0)"
9008   [(set_attr "type" "store")
9009    (set_attr "update" "yes")
9010    (set_attr "indexed" "yes,no")])
9012 (define_insn "*movsf_update1"
9013   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9014         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9015                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9016    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9017         (plus:SI (match_dup 1) (match_dup 2)))]
9018   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9019    && (!avoiding_indexed_address_p (SImode)
9020        || !gpc_reg_operand (operands[2], SImode))"
9021   "@
9022    lfsux %3,%0,%2
9023    lfsu %3,%2(%0)"
9024   [(set_attr "type" "fpload")
9025    (set_attr "update" "yes")
9026    (set_attr "indexed" "yes,no")])
9028 (define_insn "*movsf_update2"
9029   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9030                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9031         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9032    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9033         (plus:SI (match_dup 1) (match_dup 2)))]
9034   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9035    && (!avoiding_indexed_address_p (SImode)
9036        || !gpc_reg_operand (operands[2], SImode))"
9037   "@
9038    stfsux %3,%0,%2
9039    stfsu %3,%2(%0)"
9040   [(set_attr "type" "fpstore")
9041    (set_attr "update" "yes")
9042    (set_attr "indexed" "yes,no")])
9044 (define_insn "*movsf_update3"
9045   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9046         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9047                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9048    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9049         (plus:SI (match_dup 1) (match_dup 2)))]
9050   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9051    && (!avoiding_indexed_address_p (SImode)
9052        || !gpc_reg_operand (operands[2], SImode))"
9053   "@
9054    lwzux %3,%0,%2
9055    lwzu %3,%2(%0)"
9056   [(set_attr "type" "load")
9057    (set_attr "update" "yes")
9058    (set_attr "indexed" "yes,no")])
9060 (define_insn "*movsf_update4"
9061   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9062                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9063         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9064    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9065         (plus:SI (match_dup 1) (match_dup 2)))]
9066   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9067    && (!avoiding_indexed_address_p (SImode)
9068        || !gpc_reg_operand (operands[2], SImode))"
9069   "@
9070    stwux %3,%0,%2
9071    stwu %3,%2(%0)"
9072   [(set_attr "type" "store")
9073    (set_attr "update" "yes")
9074    (set_attr "indexed" "yes,no")])
9076 (define_insn "*movdf_update1"
9077   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9078         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9079                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9080    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9081         (plus:SI (match_dup 1) (match_dup 2)))]
9082   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9083    && (!avoiding_indexed_address_p (SImode)
9084        || !gpc_reg_operand (operands[2], SImode))"
9085   "@
9086    lfdux %3,%0,%2
9087    lfdu %3,%2(%0)"
9088   [(set_attr "type" "fpload")
9089    (set_attr "update" "yes")
9090    (set_attr "indexed" "yes,no")
9091    (set_attr "size" "64")])
9093 (define_insn "*movdf_update2"
9094   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9095                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9096         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9097    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9098         (plus:SI (match_dup 1) (match_dup 2)))]
9099   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9100    && (!avoiding_indexed_address_p (SImode)
9101        || !gpc_reg_operand (operands[2], SImode))"
9102   "@
9103    stfdux %3,%0,%2
9104    stfdu %3,%2(%0)"
9105   [(set_attr "type" "fpstore")
9106    (set_attr "update" "yes")
9107    (set_attr "indexed" "yes,no")])
9110 ;; After inserting conditional returns we can sometimes have
9111 ;; unnecessary register moves.  Unfortunately we cannot have a
9112 ;; modeless peephole here, because some single SImode sets have early
9113 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9114 ;; sequences, using get_attr_length here will smash the operands
9115 ;; array.  Neither is there an early_cobbler_p predicate.
9116 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9117 ;; Also this optimization interferes with scalars going into
9118 ;; altivec registers (the code does reloading through the FPRs).
9119 (define_peephole2
9120   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9121         (match_operand:DF 1 "any_operand" ""))
9122    (set (match_operand:DF 2 "gpc_reg_operand" "")
9123         (match_dup 0))]
9124   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9125    && !TARGET_UPPER_REGS_DF
9126    && peep2_reg_dead_p (2, operands[0])"
9127   [(set (match_dup 2) (match_dup 1))])
9129 (define_peephole2
9130   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9131         (match_operand:SF 1 "any_operand" ""))
9132    (set (match_operand:SF 2 "gpc_reg_operand" "")
9133         (match_dup 0))]
9134   "!TARGET_UPPER_REGS_SF
9135    && peep2_reg_dead_p (2, operands[0])"
9136   [(set (match_dup 2) (match_dup 1))])
9139 ;; TLS support.
9141 ;; Mode attributes for different ABIs.
9142 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9143 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9144 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9145 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9147 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9148   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9149         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9150               (match_operand 4 "" "g")))
9151    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9152                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9153                    UNSPEC_TLSGD)
9154    (clobber (reg:SI LR_REGNO))]
9155   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9157   if (TARGET_CMODEL != CMODEL_SMALL)
9158     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9159            "bl %z3\;nop";
9160   else
9161     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9163   "&& TARGET_TLS_MARKERS"
9164   [(set (match_dup 0)
9165         (unspec:TLSmode [(match_dup 1)
9166                          (match_dup 2)]
9167                         UNSPEC_TLSGD))
9168    (parallel [(set (match_dup 0)
9169                    (call (mem:TLSmode (match_dup 3))
9170                          (match_dup 4)))
9171               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9172               (clobber (reg:SI LR_REGNO))])]
9173   ""
9174   [(set_attr "type" "two")
9175    (set (attr "length")
9176      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9177                    (const_int 16)
9178                    (const_int 12)))])
9180 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9181   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9182         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9183               (match_operand 4 "" "g")))
9184    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9185                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9186                    UNSPEC_TLSGD)
9187    (clobber (reg:SI LR_REGNO))]
9188   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9190   if (flag_pic)
9191     {
9192       if (TARGET_SECURE_PLT && flag_pic == 2)
9193         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9194       else
9195         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9196     }
9197   else
9198     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9200   "&& TARGET_TLS_MARKERS"
9201   [(set (match_dup 0)
9202         (unspec:TLSmode [(match_dup 1)
9203                          (match_dup 2)]
9204                         UNSPEC_TLSGD))
9205    (parallel [(set (match_dup 0)
9206                    (call (mem:TLSmode (match_dup 3))
9207                          (match_dup 4)))
9208               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9209               (clobber (reg:SI LR_REGNO))])]
9210   ""
9211   [(set_attr "type" "two")
9212    (set_attr "length" "8")])
9214 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9215   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9216         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9217                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9218                         UNSPEC_TLSGD))]
9219   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9220   "addi %0,%1,%2@got@tlsgd"
9221   "&& TARGET_CMODEL != CMODEL_SMALL"
9222   [(set (match_dup 3)
9223         (high:TLSmode
9224             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9225    (set (match_dup 0)
9226         (lo_sum:TLSmode (match_dup 3)
9227             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9228   "
9230   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9232   [(set (attr "length")
9233      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9234                    (const_int 8)
9235                    (const_int 4)))])
9237 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9238   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9239      (high:TLSmode
9240        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9241                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9242                        UNSPEC_TLSGD)))]
9243   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9244   "addis %0,%1,%2@got@tlsgd@ha"
9245   [(set_attr "length" "4")])
9247 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9248   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9249      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9250        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9251                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9252                        UNSPEC_TLSGD)))]
9253   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9254   "addi %0,%1,%2@got@tlsgd@l"
9255   [(set_attr "length" "4")])
9257 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9258   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9259         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9260               (match_operand 2 "" "g")))
9261    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9262                    UNSPEC_TLSGD)
9263    (clobber (reg:SI LR_REGNO))]
9264   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9265    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9266   "bl %z1(%3@tlsgd)\;nop"
9267   [(set_attr "type" "branch")
9268    (set_attr "length" "8")])
9270 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9271   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9272         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9273               (match_operand 2 "" "g")))
9274    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9275                    UNSPEC_TLSGD)
9276    (clobber (reg:SI LR_REGNO))]
9277   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9279   if (flag_pic)
9280     {
9281       if (TARGET_SECURE_PLT && flag_pic == 2)
9282         return "bl %z1+32768(%3@tlsgd)@plt";
9283       return "bl %z1(%3@tlsgd)@plt";
9284     }
9285   return "bl %z1(%3@tlsgd)";
9287   [(set_attr "type" "branch")
9288    (set_attr "length" "4")])
9290 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9291   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9292         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9293               (match_operand 3 "" "g")))
9294    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9295                    UNSPEC_TLSLD)
9296    (clobber (reg:SI LR_REGNO))]
9297   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9299   if (TARGET_CMODEL != CMODEL_SMALL)
9300     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9301            "bl %z2\;nop";
9302   else
9303     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9305   "&& TARGET_TLS_MARKERS"
9306   [(set (match_dup 0)
9307         (unspec:TLSmode [(match_dup 1)]
9308                         UNSPEC_TLSLD))
9309    (parallel [(set (match_dup 0)
9310                    (call (mem:TLSmode (match_dup 2))
9311                          (match_dup 3)))
9312               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9313               (clobber (reg:SI LR_REGNO))])]
9314   ""
9315   [(set_attr "type" "two")
9316    (set (attr "length")
9317      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9318                    (const_int 16)
9319                    (const_int 12)))])
9321 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9322   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9323         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9324               (match_operand 3 "" "g")))
9325    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9326                    UNSPEC_TLSLD)
9327    (clobber (reg:SI LR_REGNO))]
9328   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9330   if (flag_pic)
9331     {
9332       if (TARGET_SECURE_PLT && flag_pic == 2)
9333         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9334       else
9335         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9336     }
9337   else
9338     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9340   "&& TARGET_TLS_MARKERS"
9341   [(set (match_dup 0)
9342         (unspec:TLSmode [(match_dup 1)]
9343                         UNSPEC_TLSLD))
9344    (parallel [(set (match_dup 0)
9345                    (call (mem:TLSmode (match_dup 2))
9346                          (match_dup 3)))
9347               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9348               (clobber (reg:SI LR_REGNO))])]
9349   ""
9350   [(set_attr "length" "8")])
9352 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9353   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9354         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9355                         UNSPEC_TLSLD))]
9356   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9357   "addi %0,%1,%&@got@tlsld"
9358   "&& TARGET_CMODEL != CMODEL_SMALL"
9359   [(set (match_dup 2)
9360         (high:TLSmode
9361             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9362    (set (match_dup 0)
9363         (lo_sum:TLSmode (match_dup 2)
9364             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9365   "
9367   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9369   [(set (attr "length")
9370      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9371                    (const_int 8)
9372                    (const_int 4)))])
9374 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9375   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9376      (high:TLSmode
9377        (unspec:TLSmode [(const_int 0)
9378                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9379                        UNSPEC_TLSLD)))]
9380   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9381   "addis %0,%1,%&@got@tlsld@ha"
9382   [(set_attr "length" "4")])
9384 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9385   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9386      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9387        (unspec:TLSmode [(const_int 0)
9388                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9389                        UNSPEC_TLSLD)))]
9390   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9391   "addi %0,%1,%&@got@tlsld@l"
9392   [(set_attr "length" "4")])
9394 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9395   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9396         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9397               (match_operand 2 "" "g")))
9398    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9399    (clobber (reg:SI LR_REGNO))]
9400   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9401    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9402   "bl %z1(%&@tlsld)\;nop"
9403   [(set_attr "type" "branch")
9404    (set_attr "length" "8")])
9406 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9407   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9408         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9409               (match_operand 2 "" "g")))
9410    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9411    (clobber (reg:SI LR_REGNO))]
9412   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9414   if (flag_pic)
9415     {
9416       if (TARGET_SECURE_PLT && flag_pic == 2)
9417         return "bl %z1+32768(%&@tlsld)@plt";
9418       return "bl %z1(%&@tlsld)@plt";
9419     }
9420   return "bl %z1(%&@tlsld)";
9422   [(set_attr "type" "branch")
9423    (set_attr "length" "4")])
9425 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9426   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9427         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9428                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9429                         UNSPEC_TLSDTPREL))]
9430   "HAVE_AS_TLS"
9431   "addi %0,%1,%2@dtprel")
9433 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9434   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9435         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9436                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9437                         UNSPEC_TLSDTPRELHA))]
9438   "HAVE_AS_TLS"
9439   "addis %0,%1,%2@dtprel@ha")
9441 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9442   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9443         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9444                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9445                         UNSPEC_TLSDTPRELLO))]
9446   "HAVE_AS_TLS"
9447   "addi %0,%1,%2@dtprel@l")
9449 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9450   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9451         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9452                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9453                         UNSPEC_TLSGOTDTPREL))]
9454   "HAVE_AS_TLS"
9455   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9456   "&& TARGET_CMODEL != CMODEL_SMALL"
9457   [(set (match_dup 3)
9458         (high:TLSmode
9459             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9460    (set (match_dup 0)
9461         (lo_sum:TLSmode (match_dup 3)
9462             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9463   "
9465   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9467   [(set (attr "length")
9468      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9469                    (const_int 8)
9470                    (const_int 4)))])
9472 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9473   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9474      (high:TLSmode
9475        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9476                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9477                        UNSPEC_TLSGOTDTPREL)))]
9478   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9479   "addis %0,%1,%2@got@dtprel@ha"
9480   [(set_attr "length" "4")])
9482 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9483   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9484      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9485          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9486                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9487                          UNSPEC_TLSGOTDTPREL)))]
9488   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9489   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9490   [(set_attr "length" "4")])
9492 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9493   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9494         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9495                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9496                         UNSPEC_TLSTPREL))]
9497   "HAVE_AS_TLS"
9498   "addi %0,%1,%2@tprel")
9500 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9501   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9502         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9503                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9504                         UNSPEC_TLSTPRELHA))]
9505   "HAVE_AS_TLS"
9506   "addis %0,%1,%2@tprel@ha")
9508 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9509   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9510         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9511                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9512                         UNSPEC_TLSTPRELLO))]
9513   "HAVE_AS_TLS"
9514   "addi %0,%1,%2@tprel@l")
9516 ;; "b" output constraint here and on tls_tls input to support linker tls
9517 ;; optimization.  The linker may edit the instructions emitted by a
9518 ;; tls_got_tprel/tls_tls pair to addis,addi.
9519 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9520   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9521         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9522                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9523                         UNSPEC_TLSGOTTPREL))]
9524   "HAVE_AS_TLS"
9525   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9526   "&& TARGET_CMODEL != CMODEL_SMALL"
9527   [(set (match_dup 3)
9528         (high:TLSmode
9529             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9530    (set (match_dup 0)
9531         (lo_sum:TLSmode (match_dup 3)
9532             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9533   "
9535   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9537   [(set (attr "length")
9538      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9539                    (const_int 8)
9540                    (const_int 4)))])
9542 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9543   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9544      (high:TLSmode
9545        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9546                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9547                        UNSPEC_TLSGOTTPREL)))]
9548   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9549   "addis %0,%1,%2@got@tprel@ha"
9550   [(set_attr "length" "4")])
9552 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9553   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9554      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9555          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9556                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9557                          UNSPEC_TLSGOTTPREL)))]
9558   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9559   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9560   [(set_attr "length" "4")])
9562 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9563   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9564         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9565                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9566                         UNSPEC_TLSTLS))]
9567   "TARGET_ELF && HAVE_AS_TLS"
9568   "add %0,%1,%2@tls")
9570 (define_expand "tls_get_tpointer"
9571   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9572         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9573   "TARGET_XCOFF && HAVE_AS_TLS"
9574   "
9576   emit_insn (gen_tls_get_tpointer_internal ());
9577   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9578   DONE;
9581 (define_insn "tls_get_tpointer_internal"
9582   [(set (reg:SI 3)
9583         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9584    (clobber (reg:SI LR_REGNO))]
9585   "TARGET_XCOFF && HAVE_AS_TLS"
9586   "bla __get_tpointer")
9588 (define_expand "tls_get_addr<mode>"
9589   [(set (match_operand:P 0 "gpc_reg_operand" "")
9590         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9591                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9592   "TARGET_XCOFF && HAVE_AS_TLS"
9593   "
9595   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9596   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9597   emit_insn (gen_tls_get_addr_internal<mode> ());
9598   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9599   DONE;
9602 (define_insn "tls_get_addr_internal<mode>"
9603   [(set (reg:P 3)
9604         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9605    (clobber (reg:P 0))
9606    (clobber (reg:P 4))
9607    (clobber (reg:P 5))
9608    (clobber (reg:P 11))
9609    (clobber (reg:CC CR0_REGNO))
9610    (clobber (reg:P LR_REGNO))]
9611   "TARGET_XCOFF && HAVE_AS_TLS"
9612   "bla __tls_get_addr")
9614 ;; Next come insns related to the calling sequence.
9616 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9617 ;; We move the back-chain and decrement the stack pointer.
9619 (define_expand "allocate_stack"
9620   [(set (match_operand 0 "gpc_reg_operand" "")
9621         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9622    (set (reg 1)
9623         (minus (reg 1) (match_dup 1)))]
9624   ""
9625   "
9626 { rtx chain = gen_reg_rtx (Pmode);
9627   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9628   rtx neg_op0;
9629   rtx insn, par, set, mem;
9631   emit_move_insn (chain, stack_bot);
9633   /* Check stack bounds if necessary.  */
9634   if (crtl->limit_stack)
9635     {
9636       rtx available;
9637       available = expand_binop (Pmode, sub_optab,
9638                                 stack_pointer_rtx, stack_limit_rtx,
9639                                 NULL_RTX, 1, OPTAB_WIDEN);
9640       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9641     }
9643   if (GET_CODE (operands[1]) != CONST_INT
9644       || INTVAL (operands[1]) < -32767
9645       || INTVAL (operands[1]) > 32768)
9646     {
9647       neg_op0 = gen_reg_rtx (Pmode);
9648       if (TARGET_32BIT)
9649         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9650       else
9651         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9652     }
9653   else
9654     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9656   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9657                                        : gen_movdi_di_update_stack))
9658                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9659                          chain));
9660   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9661      it now and set the alias set/attributes. The above gen_*_update
9662      calls will generate a PARALLEL with the MEM set being the first
9663      operation. */
9664   par = PATTERN (insn);
9665   gcc_assert (GET_CODE (par) == PARALLEL);
9666   set = XVECEXP (par, 0, 0);
9667   gcc_assert (GET_CODE (set) == SET);
9668   mem = SET_DEST (set);
9669   gcc_assert (MEM_P (mem));
9670   MEM_NOTRAP_P (mem) = 1;
9671   set_mem_alias_set (mem, get_frame_alias_set ());
9673   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9674   DONE;
9677 ;; These patterns say how to save and restore the stack pointer.  We need not
9678 ;; save the stack pointer at function level since we are careful to
9679 ;; preserve the backchain.  At block level, we have to restore the backchain
9680 ;; when we restore the stack pointer.
9682 ;; For nonlocal gotos, we must save both the stack pointer and its
9683 ;; backchain and restore both.  Note that in the nonlocal case, the
9684 ;; save area is a memory location.
9686 (define_expand "save_stack_function"
9687   [(match_operand 0 "any_operand" "")
9688    (match_operand 1 "any_operand" "")]
9689   ""
9690   "DONE;")
9692 (define_expand "restore_stack_function"
9693   [(match_operand 0 "any_operand" "")
9694    (match_operand 1 "any_operand" "")]
9695   ""
9696   "DONE;")
9698 ;; Adjust stack pointer (op0) to a new value (op1).
9699 ;; First copy old stack backchain to new location, and ensure that the
9700 ;; scheduler won't reorder the sp assignment before the backchain write.
9701 (define_expand "restore_stack_block"
9702   [(set (match_dup 2) (match_dup 3))
9703    (set (match_dup 4) (match_dup 2))
9704    (match_dup 5)
9705    (set (match_operand 0 "register_operand" "")
9706         (match_operand 1 "register_operand" ""))]
9707   ""
9708   "
9710   rtvec p;
9712   operands[1] = force_reg (Pmode, operands[1]);
9713   operands[2] = gen_reg_rtx (Pmode);
9714   operands[3] = gen_frame_mem (Pmode, operands[0]);
9715   operands[4] = gen_frame_mem (Pmode, operands[1]);
9716   p = rtvec_alloc (1);
9717   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9718                                   const0_rtx);
9719   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9722 (define_expand "save_stack_nonlocal"
9723   [(set (match_dup 3) (match_dup 4))
9724    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9725    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9726   ""
9727   "
9729   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9731   /* Copy the backchain to the first word, sp to the second.  */
9732   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9733   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9734   operands[3] = gen_reg_rtx (Pmode);
9735   operands[4] = gen_frame_mem (Pmode, operands[1]);
9738 (define_expand "restore_stack_nonlocal"
9739   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9740    (set (match_dup 3) (match_dup 4))
9741    (set (match_dup 5) (match_dup 2))
9742    (match_dup 6)
9743    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9744   ""
9745   "
9747   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9748   rtvec p;
9750   /* Restore the backchain from the first word, sp from the second.  */
9751   operands[2] = gen_reg_rtx (Pmode);
9752   operands[3] = gen_reg_rtx (Pmode);
9753   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9754   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9755   operands[5] = gen_frame_mem (Pmode, operands[3]);
9756   p = rtvec_alloc (1);
9757   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9758                                   const0_rtx);
9759   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9762 ;; TOC register handling.
9764 ;; Code to initialize the TOC register...
9766 (define_insn "load_toc_aix_si"
9767   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9768                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9769               (use (reg:SI 2))])]
9770   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9771   "*
9773   char buf[30];
9774   extern int need_toc_init;
9775   need_toc_init = 1;
9776   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9777   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9778   operands[2] = gen_rtx_REG (Pmode, 2);
9779   return \"lwz %0,%1(%2)\";
9781   [(set_attr "type" "load")
9782    (set_attr "update" "no")
9783    (set_attr "indexed" "no")])
9785 (define_insn "load_toc_aix_di"
9786   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9787                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9788               (use (reg:DI 2))])]
9789   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9790   "*
9792   char buf[30];
9793   extern int need_toc_init;
9794   need_toc_init = 1;
9795   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9796                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9797   if (TARGET_ELF)
9798     strcat (buf, \"@toc\");
9799   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9800   operands[2] = gen_rtx_REG (Pmode, 2);
9801   return \"ld %0,%1(%2)\";
9803   [(set_attr "type" "load")
9804    (set_attr "update" "no")
9805    (set_attr "indexed" "no")])
9807 (define_insn "load_toc_v4_pic_si"
9808   [(set (reg:SI LR_REGNO)
9809         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9810   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9811   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9812   [(set_attr "type" "branch")
9813    (set_attr "length" "4")])
9815 (define_expand "load_toc_v4_PIC_1"
9816   [(parallel [(set (reg:SI LR_REGNO)
9817                    (match_operand:SI 0 "immediate_operand" "s"))
9818               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9819   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9820    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9821   "")
9823 (define_insn "load_toc_v4_PIC_1_normal"
9824   [(set (reg:SI LR_REGNO)
9825         (match_operand:SI 0 "immediate_operand" "s"))
9826    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9827   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9828    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9829   "bcl 20,31,%0\\n%0:"
9830   [(set_attr "type" "branch")
9831    (set_attr "length" "4")
9832    (set_attr "cannot_copy" "yes")])
9834 (define_insn "load_toc_v4_PIC_1_476"
9835   [(set (reg:SI LR_REGNO)
9836         (match_operand:SI 0 "immediate_operand" "s"))
9837    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9838   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9839    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9840   "*
9842   char name[32];
9843   static char templ[32];
9845   get_ppc476_thunk_name (name);
9846   sprintf (templ, \"bl %s\\n%%0:\", name);
9847   return templ;
9849   [(set_attr "type" "branch")
9850    (set_attr "length" "4")
9851    (set_attr "cannot_copy" "yes")])
9853 (define_expand "load_toc_v4_PIC_1b"
9854   [(parallel [(set (reg:SI LR_REGNO)
9855                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9856                                (label_ref (match_operand 1 "" ""))]
9857                            UNSPEC_TOCPTR))
9858               (match_dup 1)])]
9859   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9860   "")
9862 (define_insn "load_toc_v4_PIC_1b_normal"
9863   [(set (reg:SI LR_REGNO)
9864         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9865                     (label_ref (match_operand 1 "" ""))]
9866                 UNSPEC_TOCPTR))
9867    (match_dup 1)]
9868   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9869   "bcl 20,31,$+8\;.long %0-$"
9870   [(set_attr "type" "branch")
9871    (set_attr "length" "8")])
9873 (define_insn "load_toc_v4_PIC_1b_476"
9874   [(set (reg:SI LR_REGNO)
9875         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9876                     (label_ref (match_operand 1 "" ""))]
9877                 UNSPEC_TOCPTR))
9878    (match_dup 1)]
9879   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9880   "*
9882   char name[32];
9883   static char templ[32];
9885   get_ppc476_thunk_name (name);
9886   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9887   return templ;
9889   [(set_attr "type" "branch")
9890    (set_attr "length" "16")])
9892 (define_insn "load_toc_v4_PIC_2"
9893   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9894         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9895                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9896                              (match_operand:SI 3 "immediate_operand" "s")))))]
9897   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9898   "lwz %0,%2-%3(%1)"
9899   [(set_attr "type" "load")])
9901 (define_insn "load_toc_v4_PIC_3b"
9902   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9903         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9904                  (high:SI
9905                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9906                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9907   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9908   "addis %0,%1,%2-%3@ha")
9910 (define_insn "load_toc_v4_PIC_3c"
9911   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9912         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9913                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9914                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9915   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9916   "addi %0,%1,%2-%3@l")
9918 ;; If the TOC is shared over a translation unit, as happens with all
9919 ;; the kinds of PIC that we support, we need to restore the TOC
9920 ;; pointer only when jumping over units of translation.
9921 ;; On Darwin, we need to reload the picbase.
9923 (define_expand "builtin_setjmp_receiver"
9924   [(use (label_ref (match_operand 0 "" "")))]
9925   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9926    || (TARGET_TOC && TARGET_MINIMAL_TOC)
9927    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9928   "
9930 #if TARGET_MACHO
9931   if (DEFAULT_ABI == ABI_DARWIN)
9932     {
9933       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9934       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9935       rtx tmplabrtx;
9936       char tmplab[20];
9938       crtl->uses_pic_offset_table = 1;
9939       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9940                                   CODE_LABEL_NUMBER (operands[0]));
9941       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9943       emit_insn (gen_load_macho_picbase (tmplabrtx));
9944       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9945       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9946     }
9947   else
9948 #endif
9949     rs6000_emit_load_toc_table (FALSE);
9950   DONE;
9953 ;; Largetoc support
9954 (define_insn "*largetoc_high"
9955   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9956         (high:DI
9957           (unspec [(match_operand:DI 1 "" "")
9958                    (match_operand:DI 2 "gpc_reg_operand" "b")]
9959                   UNSPEC_TOCREL)))]
9960    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9961    "addis %0,%2,%1@toc@ha")
9963 (define_insn "*largetoc_high_aix<mode>"
9964   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9965         (high:P
9966           (unspec [(match_operand:P 1 "" "")
9967                    (match_operand:P 2 "gpc_reg_operand" "b")]
9968                   UNSPEC_TOCREL)))]
9969    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9970    "addis %0,%1@u(%2)")
9972 (define_insn "*largetoc_high_plus"
9973   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9974         (high:DI
9975           (plus:DI
9976             (unspec [(match_operand:DI 1 "" "")
9977                      (match_operand:DI 2 "gpc_reg_operand" "b")]
9978                     UNSPEC_TOCREL)
9979             (match_operand:DI 3 "add_cint_operand" "n"))))]
9980    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9981    "addis %0,%2,%1+%3@toc@ha")
9983 (define_insn "*largetoc_high_plus_aix<mode>"
9984   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9985         (high:P
9986           (plus:P
9987             (unspec [(match_operand:P 1 "" "")
9988                      (match_operand:P 2 "gpc_reg_operand" "b")]
9989                     UNSPEC_TOCREL)
9990             (match_operand:P 3 "add_cint_operand" "n"))))]
9991    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9992    "addis %0,%1+%3@u(%2)")
9994 (define_insn "*largetoc_low"
9995   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9996         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9997                    (match_operand:DI 2 "" "")))]
9998    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9999    "addi %0,%1,%2@l")
10001 (define_insn "*largetoc_low_aix<mode>"
10002   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10003         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10004                    (match_operand:P 2 "" "")))]
10005    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10006    "la %0,%2@l(%1)")
10008 (define_insn_and_split "*tocref<mode>"
10009   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10010         (match_operand:P 1 "small_toc_ref" "R"))]
10011    "TARGET_TOC"
10012    "la %0,%a1"
10013    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10014   [(set (match_dup 0) (high:P (match_dup 1)))
10015    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10017 ;; Elf specific ways of loading addresses for non-PIC code.
10018 ;; The output of this could be r0, but we make a very strong
10019 ;; preference for a base register because it will usually
10020 ;; be needed there.
10021 (define_insn "elf_high"
10022   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10023         (high:SI (match_operand 1 "" "")))]
10024   "TARGET_ELF && ! TARGET_64BIT"
10025   "lis %0,%1@ha")
10027 (define_insn "elf_low"
10028   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10029         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10030                    (match_operand 2 "" "")))]
10031    "TARGET_ELF && ! TARGET_64BIT"
10032    "la %0,%2@l(%1)")
10034 ;; Call and call_value insns
10035 (define_expand "call"
10036   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10037                     (match_operand 1 "" ""))
10038               (use (match_operand 2 "" ""))
10039               (clobber (reg:SI LR_REGNO))])]
10040   ""
10041   "
10043 #if TARGET_MACHO
10044   if (MACHOPIC_INDIRECT)
10045     operands[0] = machopic_indirect_call_target (operands[0]);
10046 #endif
10048   gcc_assert (GET_CODE (operands[0]) == MEM);
10049   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10051   operands[0] = XEXP (operands[0], 0);
10053   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10054     {
10055       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10056       DONE;
10057     }
10059   if (GET_CODE (operands[0]) != SYMBOL_REF
10060       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10061     {
10062       if (INTVAL (operands[2]) & CALL_LONG)
10063         operands[0] = rs6000_longcall_ref (operands[0]);
10065       switch (DEFAULT_ABI)
10066         {
10067         case ABI_V4:
10068         case ABI_DARWIN:
10069           operands[0] = force_reg (Pmode, operands[0]);
10070           break;
10072         default:
10073           gcc_unreachable ();
10074         }
10075     }
10078 (define_expand "call_value"
10079   [(parallel [(set (match_operand 0 "" "")
10080                    (call (mem:SI (match_operand 1 "address_operand" ""))
10081                          (match_operand 2 "" "")))
10082               (use (match_operand 3 "" ""))
10083               (clobber (reg:SI LR_REGNO))])]
10084   ""
10085   "
10087 #if TARGET_MACHO
10088   if (MACHOPIC_INDIRECT)
10089     operands[1] = machopic_indirect_call_target (operands[1]);
10090 #endif
10092   gcc_assert (GET_CODE (operands[1]) == MEM);
10093   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10095   operands[1] = XEXP (operands[1], 0);
10097   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10098     {
10099       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10100       DONE;
10101     }
10103   if (GET_CODE (operands[1]) != SYMBOL_REF
10104       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10105     {
10106       if (INTVAL (operands[3]) & CALL_LONG)
10107         operands[1] = rs6000_longcall_ref (operands[1]);
10109       switch (DEFAULT_ABI)
10110         {
10111         case ABI_V4:
10112         case ABI_DARWIN:
10113           operands[1] = force_reg (Pmode, operands[1]);
10114           break;
10116         default:
10117           gcc_unreachable ();
10118         }
10119     }
10122 ;; Call to function in current module.  No TOC pointer reload needed.
10123 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10124 ;; either the function was not prototyped, or it was prototyped as a
10125 ;; variable argument function.  It is > 0 if FP registers were passed
10126 ;; and < 0 if they were not.
10128 (define_insn "*call_local32"
10129   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10130          (match_operand 1 "" "g,g"))
10131    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10132    (clobber (reg:SI LR_REGNO))]
10133   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10134   "*
10136   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10137     output_asm_insn (\"crxor 6,6,6\", operands);
10139   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10140     output_asm_insn (\"creqv 6,6,6\", operands);
10142   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10144   [(set_attr "type" "branch")
10145    (set_attr "length" "4,8")])
10147 (define_insn "*call_local64"
10148   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10149          (match_operand 1 "" "g,g"))
10150    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10151    (clobber (reg:SI LR_REGNO))]
10152   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10153   "*
10155   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10156     output_asm_insn (\"crxor 6,6,6\", operands);
10158   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10159     output_asm_insn (\"creqv 6,6,6\", operands);
10161   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10163   [(set_attr "type" "branch")
10164    (set_attr "length" "4,8")])
10166 (define_insn "*call_value_local32"
10167   [(set (match_operand 0 "" "")
10168         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10169               (match_operand 2 "" "g,g")))
10170    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10171    (clobber (reg:SI LR_REGNO))]
10172   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10173   "*
10175   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10176     output_asm_insn (\"crxor 6,6,6\", operands);
10178   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10179     output_asm_insn (\"creqv 6,6,6\", operands);
10181   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10183   [(set_attr "type" "branch")
10184    (set_attr "length" "4,8")])
10187 (define_insn "*call_value_local64"
10188   [(set (match_operand 0 "" "")
10189         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10190               (match_operand 2 "" "g,g")))
10191    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10192    (clobber (reg:SI LR_REGNO))]
10193   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10194   "*
10196   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10197     output_asm_insn (\"crxor 6,6,6\", operands);
10199   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10200     output_asm_insn (\"creqv 6,6,6\", operands);
10202   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10204   [(set_attr "type" "branch")
10205    (set_attr "length" "4,8")])
10208 ;; A function pointer under System V is just a normal pointer
10209 ;; operands[0] is the function pointer
10210 ;; operands[1] is the stack size to clean up
10211 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10212 ;; which indicates how to set cr1
10214 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10215   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10216          (match_operand 1 "" "g,g,g,g"))
10217    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10218    (clobber (reg:SI LR_REGNO))]
10219   "DEFAULT_ABI == ABI_V4
10220    || DEFAULT_ABI == ABI_DARWIN"
10222   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10223     output_asm_insn ("crxor 6,6,6", operands);
10225   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10226     output_asm_insn ("creqv 6,6,6", operands);
10228   return "b%T0l";
10230   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10231    (set_attr "length" "4,4,8,8")])
10233 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10234   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10235          (match_operand 1 "" "g,g"))
10236    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10237    (clobber (reg:SI LR_REGNO))]
10238   "(DEFAULT_ABI == ABI_DARWIN
10239    || (DEFAULT_ABI == ABI_V4
10240        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10242   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10243     output_asm_insn ("crxor 6,6,6", operands);
10245   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10246     output_asm_insn ("creqv 6,6,6", operands);
10248 #if TARGET_MACHO
10249   return output_call(insn, operands, 0, 2);
10250 #else
10251   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10252     {
10253       gcc_assert (!TARGET_SECURE_PLT);
10254       return "bl %z0@plt";
10255     }
10256   else
10257     return "bl %z0";
10258 #endif
10260   "DEFAULT_ABI == ABI_V4
10261    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10262    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10263   [(parallel [(call (mem:SI (match_dup 0))
10264                     (match_dup 1))
10265               (use (match_dup 2))
10266               (use (match_dup 3))
10267               (clobber (reg:SI LR_REGNO))])]
10269   operands[3] = pic_offset_table_rtx;
10271   [(set_attr "type" "branch,branch")
10272    (set_attr "length" "4,8")])
10274 (define_insn "*call_nonlocal_sysv_secure<mode>"
10275   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10276          (match_operand 1 "" "g,g"))
10277    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10278    (use (match_operand:SI 3 "register_operand" "r,r"))
10279    (clobber (reg:SI LR_REGNO))]
10280   "(DEFAULT_ABI == ABI_V4
10281     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10282     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10284   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10285     output_asm_insn ("crxor 6,6,6", operands);
10287   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10288     output_asm_insn ("creqv 6,6,6", operands);
10290   if (flag_pic == 2)
10291     /* The magic 32768 offset here and in the other sysv call insns
10292        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10293        See sysv4.h:toc_section.  */
10294     return "bl %z0+32768@plt";
10295   else
10296     return "bl %z0@plt";
10298   [(set_attr "type" "branch,branch")
10299    (set_attr "length" "4,8")])
10301 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10302   [(set (match_operand 0 "" "")
10303         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10304               (match_operand 2 "" "g,g,g,g")))
10305    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10306    (clobber (reg:SI LR_REGNO))]
10307   "DEFAULT_ABI == ABI_V4
10308    || DEFAULT_ABI == ABI_DARWIN"
10310   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10311     output_asm_insn ("crxor 6,6,6", operands);
10313   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10314     output_asm_insn ("creqv 6,6,6", operands);
10316   return "b%T1l";
10318   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10319    (set_attr "length" "4,4,8,8")])
10321 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10322   [(set (match_operand 0 "" "")
10323         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10324               (match_operand 2 "" "g,g")))
10325    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10326    (clobber (reg:SI LR_REGNO))]
10327   "(DEFAULT_ABI == ABI_DARWIN
10328    || (DEFAULT_ABI == ABI_V4
10329        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10331   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10332     output_asm_insn ("crxor 6,6,6", operands);
10334   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10335     output_asm_insn ("creqv 6,6,6", operands);
10337 #if TARGET_MACHO
10338   return output_call(insn, operands, 1, 3);
10339 #else
10340   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10341     {
10342       gcc_assert (!TARGET_SECURE_PLT);
10343       return "bl %z1@plt";
10344     }
10345   else
10346     return "bl %z1";
10347 #endif
10349   "DEFAULT_ABI == ABI_V4
10350    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10351    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10352   [(parallel [(set (match_dup 0)
10353                    (call (mem:SI (match_dup 1))
10354                          (match_dup 2)))
10355               (use (match_dup 3))
10356               (use (match_dup 4))
10357               (clobber (reg:SI LR_REGNO))])]
10359   operands[4] = pic_offset_table_rtx;
10361   [(set_attr "type" "branch,branch")
10362    (set_attr "length" "4,8")])
10364 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10365   [(set (match_operand 0 "" "")
10366         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10367               (match_operand 2 "" "g,g")))
10368    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10369    (use (match_operand:SI 4 "register_operand" "r,r"))
10370    (clobber (reg:SI LR_REGNO))]
10371   "(DEFAULT_ABI == ABI_V4
10372     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10373     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10375   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10376     output_asm_insn ("crxor 6,6,6", operands);
10378   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10379     output_asm_insn ("creqv 6,6,6", operands);
10381   if (flag_pic == 2)
10382     return "bl %z1+32768@plt";
10383   else
10384     return "bl %z1@plt";
10386   [(set_attr "type" "branch,branch")
10387    (set_attr "length" "4,8")])
10390 ;; Call to AIX abi function in the same module.
10392 (define_insn "*call_local_aix<mode>"
10393   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10394          (match_operand 1 "" "g"))
10395    (clobber (reg:P LR_REGNO))]
10396   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10397   "bl %z0"
10398   [(set_attr "type" "branch")
10399    (set_attr "length" "4")])
10401 (define_insn "*call_value_local_aix<mode>"
10402   [(set (match_operand 0 "" "")
10403         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10404               (match_operand 2 "" "g")))
10405    (clobber (reg:P LR_REGNO))]
10406   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10407   "bl %z1"
10408   [(set_attr "type" "branch")
10409    (set_attr "length" "4")])
10411 ;; Call to AIX abi function which may be in another module.
10412 ;; Restore the TOC pointer (r2) after the call.
10414 (define_insn "*call_nonlocal_aix<mode>"
10415   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10416          (match_operand 1 "" "g"))
10417    (clobber (reg:P LR_REGNO))]
10418   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10419   "bl %z0\;nop"
10420   [(set_attr "type" "branch")
10421    (set_attr "length" "8")])
10423 (define_insn "*call_value_nonlocal_aix<mode>"
10424   [(set (match_operand 0 "" "")
10425         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10426               (match_operand 2 "" "g")))
10427    (clobber (reg:P LR_REGNO))]
10428   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10429   "bl %z1\;nop"
10430   [(set_attr "type" "branch")
10431    (set_attr "length" "8")])
10433 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10434 ;; Operand0 is the addresss of the function to call
10435 ;; Operand2 is the location in the function descriptor to load r2 from
10436 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10438 (define_insn "*call_indirect_aix<mode>"
10439   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10440          (match_operand 1 "" "g,g"))
10441    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10442    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10443    (clobber (reg:P LR_REGNO))]
10444   "DEFAULT_ABI == ABI_AIX"
10445   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10446   [(set_attr "type" "jmpreg")
10447    (set_attr "length" "12")])
10449 (define_insn "*call_value_indirect_aix<mode>"
10450   [(set (match_operand 0 "" "")
10451         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10452               (match_operand 2 "" "g,g")))
10453    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10454    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10455    (clobber (reg:P LR_REGNO))]
10456   "DEFAULT_ABI == ABI_AIX"
10457   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10458   [(set_attr "type" "jmpreg")
10459    (set_attr "length" "12")])
10461 ;; Call to indirect functions with the ELFv2 ABI.
10462 ;; Operand0 is the addresss of the function to call
10463 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10465 (define_insn "*call_indirect_elfv2<mode>"
10466   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10467          (match_operand 1 "" "g,g"))
10468    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10469    (clobber (reg:P LR_REGNO))]
10470   "DEFAULT_ABI == ABI_ELFv2"
10471   "b%T0l\;<ptrload> 2,%2(1)"
10472   [(set_attr "type" "jmpreg")
10473    (set_attr "length" "8")])
10475 (define_insn "*call_value_indirect_elfv2<mode>"
10476   [(set (match_operand 0 "" "")
10477         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10478               (match_operand 2 "" "g,g")))
10479    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10480    (clobber (reg:P LR_REGNO))]
10481   "DEFAULT_ABI == ABI_ELFv2"
10482   "b%T1l\;<ptrload> 2,%3(1)"
10483   [(set_attr "type" "jmpreg")
10484    (set_attr "length" "8")])
10487 ;; Call subroutine returning any type.
10488 (define_expand "untyped_call"
10489   [(parallel [(call (match_operand 0 "" "")
10490                     (const_int 0))
10491               (match_operand 1 "" "")
10492               (match_operand 2 "" "")])]
10493   ""
10494   "
10496   int i;
10498   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10500   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10501     {
10502       rtx set = XVECEXP (operands[2], 0, i);
10503       emit_move_insn (SET_DEST (set), SET_SRC (set));
10504     }
10506   /* The optimizer does not know that the call sets the function value
10507      registers we stored in the result block.  We avoid problems by
10508      claiming that all hard registers are used and clobbered at this
10509      point.  */
10510   emit_insn (gen_blockage ());
10512   DONE;
10515 ;; sibling call patterns
10516 (define_expand "sibcall"
10517   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10518                     (match_operand 1 "" ""))
10519               (use (match_operand 2 "" ""))
10520               (use (reg:SI LR_REGNO))
10521               (simple_return)])]
10522   ""
10523   "
10525 #if TARGET_MACHO
10526   if (MACHOPIC_INDIRECT)
10527     operands[0] = machopic_indirect_call_target (operands[0]);
10528 #endif
10530   gcc_assert (GET_CODE (operands[0]) == MEM);
10531   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10533   operands[0] = XEXP (operands[0], 0);
10535   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10536     {
10537       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10538       DONE;
10539     }
10542 (define_expand "sibcall_value"
10543   [(parallel [(set (match_operand 0 "register_operand" "")
10544                 (call (mem:SI (match_operand 1 "address_operand" ""))
10545                       (match_operand 2 "" "")))
10546               (use (match_operand 3 "" ""))
10547               (use (reg:SI LR_REGNO))
10548               (simple_return)])]
10549   ""
10550   "
10552 #if TARGET_MACHO
10553   if (MACHOPIC_INDIRECT)
10554     operands[1] = machopic_indirect_call_target (operands[1]);
10555 #endif
10557   gcc_assert (GET_CODE (operands[1]) == MEM);
10558   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10560   operands[1] = XEXP (operands[1], 0);
10562   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10563     {
10564       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10565       DONE;
10566     }
10569 ;; this and similar patterns must be marked as using LR, otherwise
10570 ;; dataflow will try to delete the store into it.  This is true
10571 ;; even when the actual reg to jump to is in CTR, when LR was
10572 ;; saved and restored around the PIC-setting BCL.
10573 (define_insn "*sibcall_local32"
10574   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10575          (match_operand 1 "" "g,g"))
10576    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10577    (use (reg:SI LR_REGNO))
10578    (simple_return)]
10579   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10580   "*
10582   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10583     output_asm_insn (\"crxor 6,6,6\", operands);
10585   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10586     output_asm_insn (\"creqv 6,6,6\", operands);
10588   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10590   [(set_attr "type" "branch")
10591    (set_attr "length" "4,8")])
10593 (define_insn "*sibcall_local64"
10594   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10595          (match_operand 1 "" "g,g"))
10596    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10597    (use (reg:SI LR_REGNO))
10598    (simple_return)]
10599   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10600   "*
10602   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10603     output_asm_insn (\"crxor 6,6,6\", operands);
10605   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10606     output_asm_insn (\"creqv 6,6,6\", operands);
10608   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10610   [(set_attr "type" "branch")
10611    (set_attr "length" "4,8")])
10613 (define_insn "*sibcall_value_local32"
10614   [(set (match_operand 0 "" "")
10615         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10616               (match_operand 2 "" "g,g")))
10617    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10618    (use (reg:SI LR_REGNO))
10619    (simple_return)]
10620   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10621   "*
10623   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10624     output_asm_insn (\"crxor 6,6,6\", operands);
10626   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10627     output_asm_insn (\"creqv 6,6,6\", operands);
10629   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10631   [(set_attr "type" "branch")
10632    (set_attr "length" "4,8")])
10634 (define_insn "*sibcall_value_local64"
10635   [(set (match_operand 0 "" "")
10636         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10637               (match_operand 2 "" "g,g")))
10638    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10639    (use (reg:SI LR_REGNO))
10640    (simple_return)]
10641   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10642   "*
10644   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10645     output_asm_insn (\"crxor 6,6,6\", operands);
10647   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10648     output_asm_insn (\"creqv 6,6,6\", operands);
10650   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10652   [(set_attr "type" "branch")
10653    (set_attr "length" "4,8")])
10655 (define_insn "*sibcall_nonlocal_sysv<mode>"
10656   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10657          (match_operand 1 "" ""))
10658    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10659    (use (reg:SI LR_REGNO))
10660    (simple_return)]
10661   "(DEFAULT_ABI == ABI_DARWIN
10662     || DEFAULT_ABI == ABI_V4)
10663    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10664   "*
10666   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10667     output_asm_insn (\"crxor 6,6,6\", operands);
10669   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10670     output_asm_insn (\"creqv 6,6,6\", operands);
10672   if (which_alternative >= 2)
10673     return \"b%T0\";
10674   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10675     {
10676       gcc_assert (!TARGET_SECURE_PLT);
10677       return \"b %z0@plt\";
10678     }
10679   else
10680     return \"b %z0\";
10682   [(set_attr "type" "branch")
10683    (set_attr "length" "4,8,4,8")])
10685 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10686   [(set (match_operand 0 "" "")
10687         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10688               (match_operand 2 "" "")))
10689    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10690    (use (reg:SI LR_REGNO))
10691    (simple_return)]
10692   "(DEFAULT_ABI == ABI_DARWIN
10693     || DEFAULT_ABI == ABI_V4)
10694    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10695   "*
10697   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10698     output_asm_insn (\"crxor 6,6,6\", operands);
10700   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10701     output_asm_insn (\"creqv 6,6,6\", operands);
10703   if (which_alternative >= 2)
10704     return \"b%T1\";
10705   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10706     {
10707       gcc_assert (!TARGET_SECURE_PLT);
10708       return \"b %z1@plt\";
10709     }
10710   else
10711     return \"b %z1\";
10713   [(set_attr "type" "branch")
10714    (set_attr "length" "4,8,4,8")])
10716 ;; AIX ABI sibling call patterns.
10718 (define_insn "*sibcall_aix<mode>"
10719   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10720          (match_operand 1 "" "g,g"))
10721    (simple_return)]
10722   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10723   "@
10724    b %z0
10725    b%T0"
10726   [(set_attr "type" "branch")
10727    (set_attr "length" "4")])
10729 (define_insn "*sibcall_value_aix<mode>"
10730   [(set (match_operand 0 "" "")
10731         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10732               (match_operand 2 "" "g,g")))
10733    (simple_return)]
10734   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10735   "@
10736    b %z1
10737    b%T1"
10738   [(set_attr "type" "branch")
10739    (set_attr "length" "4")])
10741 (define_expand "sibcall_epilogue"
10742   [(use (const_int 0))]
10743   ""
10745   if (!TARGET_SCHED_PROLOG)
10746     emit_insn (gen_blockage ());
10747   rs6000_emit_epilogue (TRUE);
10748   DONE;
10751 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10752 ;; all of memory.  This blocks insns from being moved across this point.
10754 (define_insn "blockage"
10755   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10756   ""
10757   "")
10759 (define_expand "probe_stack_address"
10760   [(use (match_operand 0 "address_operand"))]
10761   ""
10763   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10764   MEM_VOLATILE_P (operands[0]) = 1;
10766   if (TARGET_64BIT)
10767     emit_insn (gen_probe_stack_di (operands[0]));
10768   else
10769     emit_insn (gen_probe_stack_si (operands[0]));
10770   DONE;
10773 (define_insn "probe_stack_<mode>"
10774   [(set (match_operand:P 0 "memory_operand" "=m")
10775         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10776   ""
10778   operands[1] = gen_rtx_REG (Pmode, 0);
10779   return "st<wd>%U0%X0 %1,%0";
10781   [(set_attr "type" "store")
10782    (set (attr "update")
10783         (if_then_else (match_operand 0 "update_address_mem")
10784                       (const_string "yes")
10785                       (const_string "no")))
10786    (set (attr "indexed")
10787         (if_then_else (match_operand 0 "indexed_address_mem")
10788                       (const_string "yes")
10789                       (const_string "no")))
10790    (set_attr "length" "4")])
10792 (define_insn "probe_stack_range<P:mode>"
10793   [(set (match_operand:P 0 "register_operand" "=r")
10794         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10795                             (match_operand:P 2 "register_operand" "r")]
10796                            UNSPECV_PROBE_STACK_RANGE))]
10797   ""
10798   "* return output_probe_stack_range (operands[0], operands[2]);"
10799   [(set_attr "type" "three")])
10801 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10802 ;; signed & unsigned, and one type of branch.
10804 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10805 ;; insns, and branches.
10807 (define_expand "cbranch<mode>4"
10808   [(use (match_operator 0 "rs6000_cbranch_operator"
10809          [(match_operand:GPR 1 "gpc_reg_operand" "")
10810           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10811    (use (match_operand 3 ""))]
10812   ""
10813   "
10815   /* Take care of the possibility that operands[2] might be negative but
10816      this might be a logical operation.  That insn doesn't exist.  */
10817   if (GET_CODE (operands[2]) == CONST_INT
10818       && INTVAL (operands[2]) < 0)
10819     {
10820       operands[2] = force_reg (<MODE>mode, operands[2]);
10821       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10822                                     GET_MODE (operands[0]),
10823                                     operands[1], operands[2]);
10824    }
10826   rs6000_emit_cbranch (<MODE>mode, operands);
10827   DONE;
10830 (define_expand "cbranch<mode>4"
10831   [(use (match_operator 0 "rs6000_cbranch_operator"
10832          [(match_operand:FP 1 "gpc_reg_operand" "")
10833           (match_operand:FP 2 "gpc_reg_operand" "")]))
10834    (use (match_operand 3 ""))]
10835   ""
10836   "
10838   rs6000_emit_cbranch (<MODE>mode, operands);
10839   DONE;
10842 (define_expand "cstore<mode>4_signed"
10843   [(use (match_operator 1 "signed_comparison_operator"
10844          [(match_operand:P 2 "gpc_reg_operand")
10845           (match_operand:P 3 "gpc_reg_operand")]))
10846    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10847   ""
10849   enum rtx_code cond_code = GET_CODE (operands[1]);
10851   rtx op0 = operands[0];
10852   rtx op1 = operands[2];
10853   rtx op2 = operands[3];
10855   if (cond_code == GE || cond_code == LT)
10856     {
10857       cond_code = swap_condition (cond_code);
10858       std::swap (op1, op2);
10859     }
10861   rtx tmp1 = gen_reg_rtx (<MODE>mode);
10862   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10863   rtx tmp3 = gen_reg_rtx (<MODE>mode);
10865   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10866   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10867   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10869   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10871   if (cond_code == LE)
10872     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10873   else
10874     {
10875       rtx tmp4 = gen_reg_rtx (<MODE>mode);
10876       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10877       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10878     }
10880   DONE;
10883 (define_expand "cstore<mode>4_unsigned"
10884   [(use (match_operator 1 "unsigned_comparison_operator"
10885          [(match_operand:P 2 "gpc_reg_operand")
10886           (match_operand:P 3 "reg_or_short_operand")]))
10887    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10888   ""
10890   enum rtx_code cond_code = GET_CODE (operands[1]);
10892   rtx op0 = operands[0];
10893   rtx op1 = operands[2];
10894   rtx op2 = operands[3];
10896   if (cond_code == GEU || cond_code == LTU)
10897     {
10898       cond_code = swap_condition (cond_code);
10899       std::swap (op1, op2);
10900     }
10902   if (!gpc_reg_operand (op1, <MODE>mode))
10903     op1 = force_reg (<MODE>mode, op1);
10904   if (!reg_or_short_operand (op2, <MODE>mode))
10905     op2 = force_reg (<MODE>mode, op2);
10907   rtx tmp = gen_reg_rtx (<MODE>mode);
10908   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10910   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10911   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10913   if (cond_code == LEU)
10914     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10915   else
10916     emit_insn (gen_neg<mode>2 (op0, tmp2));
10918   DONE;
10921 (define_expand "cstore_si_as_di"
10922   [(use (match_operator 1 "unsigned_comparison_operator"
10923          [(match_operand:SI 2 "gpc_reg_operand")
10924           (match_operand:SI 3 "reg_or_short_operand")]))
10925    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10926   ""
10928   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10929   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10931   operands[2] = force_reg (SImode, operands[2]);
10932   operands[3] = force_reg (SImode, operands[3]);
10933   rtx op1 = gen_reg_rtx (DImode);
10934   rtx op2 = gen_reg_rtx (DImode);
10935   convert_move (op1, operands[2], uns_flag);
10936   convert_move (op2, operands[3], uns_flag);
10938   if (cond_code == GT || cond_code == LE)
10939     {
10940       cond_code = swap_condition (cond_code);
10941       std::swap (op1, op2);
10942     }
10944   rtx tmp = gen_reg_rtx (DImode);
10945   rtx tmp2 = gen_reg_rtx (DImode);
10946   emit_insn (gen_subdi3 (tmp, op1, op2));
10947   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10949   rtx tmp3;
10950   switch (cond_code)
10951     {
10952     default:
10953       gcc_unreachable ();
10954     case LT:
10955       tmp3 = tmp2;
10956       break;
10957     case GE:
10958       tmp3 = gen_reg_rtx (DImode);
10959       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10960       break;
10961     }
10963   convert_move (operands[0], tmp3, 1);
10965   DONE;
10968 (define_expand "cstore<mode>4_signed_imm"
10969   [(use (match_operator 1 "signed_comparison_operator"
10970          [(match_operand:GPR 2 "gpc_reg_operand")
10971           (match_operand:GPR 3 "immediate_operand")]))
10972    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10973   ""
10975   bool invert = false;
10977   enum rtx_code cond_code = GET_CODE (operands[1]);
10979   rtx op0 = operands[0];
10980   rtx op1 = operands[2];
10981   HOST_WIDE_INT val = INTVAL (operands[3]);
10983   if (cond_code == GE || cond_code == GT)
10984     {
10985       cond_code = reverse_condition (cond_code);
10986       invert = true;
10987     }
10989   if (cond_code == LE)
10990     val++;
10992   rtx tmp = gen_reg_rtx (<MODE>mode);
10993   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10994   rtx x = gen_reg_rtx (<MODE>mode);
10995   if (val < 0)
10996     emit_insn (gen_and<mode>3 (x, op1, tmp));
10997   else
10998     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11000   if (invert)
11001     {
11002       rtx tmp = gen_reg_rtx (<MODE>mode);
11003       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11004       x = tmp;
11005     }
11007   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11008   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11010   DONE;
11013 (define_expand "cstore<mode>4_unsigned_imm"
11014   [(use (match_operator 1 "unsigned_comparison_operator"
11015          [(match_operand:GPR 2 "gpc_reg_operand")
11016           (match_operand:GPR 3 "immediate_operand")]))
11017    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11018   ""
11020   bool invert = false;
11022   enum rtx_code cond_code = GET_CODE (operands[1]);
11024   rtx op0 = operands[0];
11025   rtx op1 = operands[2];
11026   HOST_WIDE_INT val = INTVAL (operands[3]);
11028   if (cond_code == GEU || cond_code == GTU)
11029     {
11030       cond_code = reverse_condition (cond_code);
11031       invert = true;
11032     }
11034   if (cond_code == LEU)
11035     val++;
11037   rtx tmp = gen_reg_rtx (<MODE>mode);
11038   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11039   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11040   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11041   rtx x = gen_reg_rtx (<MODE>mode);
11042   if (val < 0)
11043     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11044   else
11045     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11047   if (invert)
11048     {
11049       rtx tmp = gen_reg_rtx (<MODE>mode);
11050       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11051       x = tmp;
11052     }
11054   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11055   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11057   DONE;
11060 (define_expand "cstore<mode>4"
11061   [(use (match_operator 1 "rs6000_cbranch_operator"
11062          [(match_operand:GPR 2 "gpc_reg_operand")
11063           (match_operand:GPR 3 "reg_or_short_operand")]))
11064    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11065   ""
11067   /* Use ISEL if the user asked for it.  */
11068   if (TARGET_ISEL)
11069     rs6000_emit_sISEL (<MODE>mode, operands);
11071   /* Expanding EQ and NE directly to some machine instructions does not help
11072      but does hurt combine.  So don't.  */
11073   else if (GET_CODE (operands[1]) == EQ)
11074     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11075   else if (<MODE>mode == Pmode
11076            && GET_CODE (operands[1]) == NE)
11077     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11078   else if (GET_CODE (operands[1]) == NE)
11079     {
11080       rtx tmp = gen_reg_rtx (<MODE>mode);
11081       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11082       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11083     }
11085   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11086      etc. combinations magically work out just right.  */
11087   else if (<MODE>mode == Pmode
11088            && unsigned_comparison_operator (operands[1], VOIDmode))
11089     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11090                                            operands[2], operands[3]));
11092   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11093   else if (<MODE>mode == SImode && Pmode == DImode)
11094     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11095                                     operands[2], operands[3]));
11097   /* For signed comparisons against a constant, we can do some simple
11098      bit-twiddling.  */
11099   else if (signed_comparison_operator (operands[1], VOIDmode)
11100            && CONST_INT_P (operands[3]))
11101     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11102                                              operands[2], operands[3]));
11104   /* And similarly for unsigned comparisons.  */
11105   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11106            && CONST_INT_P (operands[3]))
11107     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11108                                                operands[2], operands[3]));
11110   /* We also do not want to use mfcr for signed comparisons.  */
11111   else if (<MODE>mode == Pmode
11112            && signed_comparison_operator (operands[1], VOIDmode))
11113     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11114                                          operands[2], operands[3]));
11116   /* Everything else, use the mfcr brute force.  */
11117   else
11118     rs6000_emit_sCOND (<MODE>mode, operands);
11120   DONE;
11123 (define_expand "cstore<mode>4"
11124   [(use (match_operator 1 "rs6000_cbranch_operator"
11125          [(match_operand:FP 2 "gpc_reg_operand")
11126           (match_operand:FP 3 "gpc_reg_operand")]))
11127    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11128   ""
11130   rs6000_emit_sCOND (<MODE>mode, operands);
11131   DONE;
11135 (define_expand "stack_protect_set"
11136   [(match_operand 0 "memory_operand" "")
11137    (match_operand 1 "memory_operand" "")]
11138   ""
11140 #ifdef TARGET_THREAD_SSP_OFFSET
11141   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11142   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11143   operands[1] = gen_rtx_MEM (Pmode, addr);
11144 #endif
11145   if (TARGET_64BIT)
11146     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11147   else
11148     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11149   DONE;
11152 (define_insn "stack_protect_setsi"
11153   [(set (match_operand:SI 0 "memory_operand" "=m")
11154         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11155    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11156   "TARGET_32BIT"
11157   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11158   [(set_attr "type" "three")
11159    (set_attr "length" "12")])
11161 (define_insn "stack_protect_setdi"
11162   [(set (match_operand:DI 0 "memory_operand" "=Y")
11163         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11164    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11165   "TARGET_64BIT"
11166   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11167   [(set_attr "type" "three")
11168    (set_attr "length" "12")])
11170 (define_expand "stack_protect_test"
11171   [(match_operand 0 "memory_operand" "")
11172    (match_operand 1 "memory_operand" "")
11173    (match_operand 2 "" "")]
11174   ""
11176   rtx test, op0, op1;
11177 #ifdef TARGET_THREAD_SSP_OFFSET
11178   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11179   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11180   operands[1] = gen_rtx_MEM (Pmode, addr);
11181 #endif
11182   op0 = operands[0];
11183   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11184   test = gen_rtx_EQ (VOIDmode, op0, op1);
11185   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11186   DONE;
11189 (define_insn "stack_protect_testsi"
11190   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11191         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11192                       (match_operand:SI 2 "memory_operand" "m,m")]
11193                      UNSPEC_SP_TEST))
11194    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11195    (clobber (match_scratch:SI 3 "=&r,&r"))]
11196   "TARGET_32BIT"
11197   "@
11198    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11199    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11200   [(set_attr "length" "16,20")])
11202 (define_insn "stack_protect_testdi"
11203   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11204         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11205                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11206                      UNSPEC_SP_TEST))
11207    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11208    (clobber (match_scratch:DI 3 "=&r,&r"))]
11209   "TARGET_64BIT"
11210   "@
11211    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11212    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11213   [(set_attr "length" "16,20")])
11216 ;; Here are the actual compare insns.
11217 (define_insn "*cmp<mode>_signed"
11218   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11219         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11220                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11221   ""
11222   "cmp<wd>%I2 %0,%1,%2"
11223   [(set_attr "type" "cmp")])
11225 (define_insn "*cmp<mode>_unsigned"
11226   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11227         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11228                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11229   ""
11230   "cmpl<wd>%I2 %0,%1,%2"
11231   [(set_attr "type" "cmp")])
11233 ;; If we are comparing a register for equality with a large constant,
11234 ;; we can do this with an XOR followed by a compare.  But this is profitable
11235 ;; only if the large constant is only used for the comparison (and in this
11236 ;; case we already have a register to reuse as scratch).
11238 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11239 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11241 (define_peephole2
11242   [(set (match_operand:SI 0 "register_operand")
11243         (match_operand:SI 1 "logical_const_operand" ""))
11244    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11245                        [(match_dup 0)
11246                         (match_operand:SI 2 "logical_const_operand" "")]))
11247    (set (match_operand:CC 4 "cc_reg_operand" "")
11248         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11249                     (match_dup 0)))
11250    (set (pc)
11251         (if_then_else (match_operator 6 "equality_operator"
11252                        [(match_dup 4) (const_int 0)])
11253                       (match_operand 7 "" "")
11254                       (match_operand 8 "" "")))]
11255   "peep2_reg_dead_p (3, operands[0])
11256    && peep2_reg_dead_p (4, operands[4])
11257    && REGNO (operands[0]) != REGNO (operands[5])"
11258  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11259   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11260   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11263   /* Get the constant we are comparing against, and see what it looks like
11264      when sign-extended from 16 to 32 bits.  Then see what constant we could
11265      XOR with SEXTC to get the sign-extended value.  */
11266   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11267                                               SImode,
11268                                               operands[1], operands[2]);
11269   HOST_WIDE_INT c = INTVAL (cnst);
11270   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11271   HOST_WIDE_INT xorv = c ^ sextc;
11273   operands[9] = GEN_INT (xorv);
11274   operands[10] = GEN_INT (sextc);
11277 ;; The following two insns don't exist as single insns, but if we provide
11278 ;; them, we can swap an add and compare, which will enable us to overlap more
11279 ;; of the required delay between a compare and branch.  We generate code for
11280 ;; them by splitting.
11282 (define_insn ""
11283   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11284         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11285                     (match_operand:SI 2 "short_cint_operand" "i")))
11286    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11287         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11288   ""
11289   "#"
11290   [(set_attr "length" "8")])
11292 (define_insn ""
11293   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11294         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11295                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11296    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11297         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11298   ""
11299   "#"
11300   [(set_attr "length" "8")])
11302 (define_split
11303   [(set (match_operand:CC 3 "cc_reg_operand" "")
11304         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11305                     (match_operand:SI 2 "short_cint_operand" "")))
11306    (set (match_operand:SI 0 "gpc_reg_operand" "")
11307         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11308   ""
11309   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11310    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11312 (define_split
11313   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11314         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11315                        (match_operand:SI 2 "u_short_cint_operand" "")))
11316    (set (match_operand:SI 0 "gpc_reg_operand" "")
11317         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11318   ""
11319   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11320    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11322 ;; Only need to compare second words if first words equal
11323 (define_insn "*cmp<mode>_internal1"
11324   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11325         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11326                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11327   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11328    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11329   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11330   [(set_attr "type" "fpcompare")
11331    (set_attr "length" "12")])
11333 (define_insn_and_split "*cmp<mode>_internal2"
11334   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11335         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11336                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11337     (clobber (match_scratch:DF 3 "=d"))
11338     (clobber (match_scratch:DF 4 "=d"))
11339     (clobber (match_scratch:DF 5 "=d"))
11340     (clobber (match_scratch:DF 6 "=d"))
11341     (clobber (match_scratch:DF 7 "=d"))
11342     (clobber (match_scratch:DF 8 "=d"))
11343     (clobber (match_scratch:DF 9 "=d"))
11344     (clobber (match_scratch:DF 10 "=d"))
11345     (clobber (match_scratch:GPR 11 "=b"))]
11346   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11347    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11348   "#"
11349   "&& reload_completed"
11350   [(set (match_dup 3) (match_dup 14))
11351    (set (match_dup 4) (match_dup 15))
11352    (set (match_dup 9) (abs:DF (match_dup 5)))
11353    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11354    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11355                            (label_ref (match_dup 12))
11356                            (pc)))
11357    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11358    (set (pc) (label_ref (match_dup 13)))
11359    (match_dup 12)
11360    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11361    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11362    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11363    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11364    (match_dup 13)]
11366   REAL_VALUE_TYPE rv;
11367   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11368   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11370   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11371   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11372   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11373   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11374   operands[12] = gen_label_rtx ();
11375   operands[13] = gen_label_rtx ();
11376   real_inf (&rv);
11377   operands[14] = force_const_mem (DFmode,
11378                                   const_double_from_real_value (rv, DFmode));
11379   operands[15] = force_const_mem (DFmode,
11380                                   const_double_from_real_value (dconst0,
11381                                                                 DFmode));
11382   if (TARGET_TOC)
11383     {
11384       rtx tocref;
11385       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11386       operands[14] = gen_const_mem (DFmode, tocref);
11387       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11388       operands[15] = gen_const_mem (DFmode, tocref);
11389       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11390       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11391     }
11394 ;; Now we have the scc insns.  We can do some combinations because of the
11395 ;; way the machine works.
11397 ;; Note that this is probably faster if we can put an insn between the
11398 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11399 ;; cases the insns below which don't use an intermediate CR field will
11400 ;; be used instead.
11401 (define_insn ""
11402   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11403         (match_operator:SI 1 "scc_comparison_operator"
11404                            [(match_operand 2 "cc_reg_operand" "y")
11405                             (const_int 0)]))]
11406   ""
11407   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11408   [(set (attr "type")
11409      (cond [(match_test "TARGET_MFCRF")
11410                 (const_string "mfcrf")
11411            ]
11412         (const_string "mfcr")))
11413    (set_attr "length" "8")])
11415 ;; Same as above, but get the GT bit.
11416 (define_insn "move_from_CR_gt_bit"
11417   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11418         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11419   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11420   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11421   [(set_attr "type" "mfcr")
11422    (set_attr "length" "8")])
11424 ;; Same as above, but get the OV/ORDERED bit.
11425 (define_insn "move_from_CR_ov_bit"
11426   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11427         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11428                    UNSPEC_MV_CR_OV))]
11429   "TARGET_ISEL"
11430   "mfcr %0\;rlwinm %0,%0,%t1,1"
11431   [(set_attr "type" "mfcr")
11432    (set_attr "length" "8")])
11434 (define_insn ""
11435   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11436         (match_operator:DI 1 "scc_comparison_operator"
11437                            [(match_operand 2 "cc_reg_operand" "y")
11438                             (const_int 0)]))]
11439   "TARGET_POWERPC64"
11440   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11441   [(set (attr "type")
11442      (cond [(match_test "TARGET_MFCRF")
11443                 (const_string "mfcrf")
11444            ]
11445         (const_string "mfcr")))
11446    (set_attr "length" "8")])
11448 (define_insn ""
11449   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11450         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11451                                        [(match_operand 2 "cc_reg_operand" "y,y")
11452                                         (const_int 0)])
11453                     (const_int 0)))
11454    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11455         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11456   "TARGET_32BIT"
11457   "@
11458    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11459    #"
11460   [(set_attr "type" "shift")
11461    (set_attr "dot" "yes")
11462    (set_attr "length" "8,16")])
11464 (define_split
11465   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11466         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11467                                        [(match_operand 2 "cc_reg_operand" "")
11468                                         (const_int 0)])
11469                     (const_int 0)))
11470    (set (match_operand:SI 3 "gpc_reg_operand" "")
11471         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11472   "TARGET_32BIT && reload_completed"
11473   [(set (match_dup 3)
11474         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11475    (set (match_dup 0)
11476         (compare:CC (match_dup 3)
11477                     (const_int 0)))]
11478   "")
11480 (define_insn ""
11481   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11482         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11483                                       [(match_operand 2 "cc_reg_operand" "y")
11484                                        (const_int 0)])
11485                    (match_operand:SI 3 "const_int_operand" "n")))]
11486   ""
11487   "*
11489   int is_bit = ccr_bit (operands[1], 1);
11490   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11491   int count;
11493   if (is_bit >= put_bit)
11494     count = is_bit - put_bit;
11495   else
11496     count = 32 - (put_bit - is_bit);
11498   operands[4] = GEN_INT (count);
11499   operands[5] = GEN_INT (put_bit);
11501   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11503   [(set (attr "type")
11504      (cond [(match_test "TARGET_MFCRF")
11505                 (const_string "mfcrf")
11506            ]
11507         (const_string "mfcr")))
11508    (set_attr "length" "8")])
11510 (define_insn ""
11511   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11512         (compare:CC
11513          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11514                                        [(match_operand 2 "cc_reg_operand" "y,y")
11515                                         (const_int 0)])
11516                     (match_operand:SI 3 "const_int_operand" "n,n"))
11517          (const_int 0)))
11518    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11519         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11520                    (match_dup 3)))]
11521   ""
11522   "*
11524   int is_bit = ccr_bit (operands[1], 1);
11525   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11526   int count;
11528   /* Force split for non-cc0 compare.  */
11529   if (which_alternative == 1)
11530      return \"#\";
11532   if (is_bit >= put_bit)
11533     count = is_bit - put_bit;
11534   else
11535     count = 32 - (put_bit - is_bit);
11537   operands[5] = GEN_INT (count);
11538   operands[6] = GEN_INT (put_bit);
11540   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11542   [(set_attr "type" "shift")
11543    (set_attr "dot" "yes")
11544    (set_attr "length" "8,16")])
11546 (define_split
11547   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11548         (compare:CC
11549          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11550                                        [(match_operand 2 "cc_reg_operand" "")
11551                                         (const_int 0)])
11552                     (match_operand:SI 3 "const_int_operand" ""))
11553          (const_int 0)))
11554    (set (match_operand:SI 4 "gpc_reg_operand" "")
11555         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11556                    (match_dup 3)))]
11557   "reload_completed"
11558   [(set (match_dup 4)
11559         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11560                    (match_dup 3)))
11561    (set (match_dup 0)
11562         (compare:CC (match_dup 4)
11563                     (const_int 0)))]
11564   "")
11567 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11568                               (DI "rKJI")])
11570 (define_insn_and_split "eq<mode>3"
11571   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11572         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11573                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11574    (clobber (match_scratch:GPR 3 "=r"))
11575    (clobber (match_scratch:GPR 4 "=r"))]
11576   ""
11577   "#"
11578   ""
11579   [(set (match_dup 4)
11580         (clz:GPR (match_dup 3)))
11581    (set (match_dup 0)
11582         (lshiftrt:GPR (match_dup 4)
11583                       (match_dup 5)))]
11585   operands[3] = rs6000_emit_eqne (<MODE>mode,
11586                                   operands[1], operands[2], operands[3]);
11588   if (GET_CODE (operands[4]) == SCRATCH)
11589     operands[4] = gen_reg_rtx (<MODE>mode);
11591   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11593   [(set (attr "length")
11594         (if_then_else (match_test "operands[2] == const0_rtx")
11595                       (const_string "8")
11596                       (const_string "12")))])
11598 (define_insn_and_split "ne<mode>3"
11599   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11600         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11601               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11602    (clobber (match_scratch:P 3 "=r"))
11603    (clobber (match_scratch:P 4 "=r"))
11604    (clobber (reg:P CA_REGNO))]
11605   "!TARGET_ISEL"
11606   "#"
11607   ""
11608   [(parallel [(set (match_dup 4)
11609                    (plus:P (match_dup 3)
11610                            (const_int -1)))
11611               (set (reg:P CA_REGNO)
11612                    (ne:P (match_dup 3)
11613                          (const_int 0)))])
11614    (parallel [(set (match_dup 0)
11615                    (plus:P (plus:P (not:P (match_dup 4))
11616                                    (reg:P CA_REGNO))
11617                            (match_dup 3)))
11618               (clobber (reg:P CA_REGNO))])]
11620   operands[3] = rs6000_emit_eqne (<MODE>mode,
11621                                   operands[1], operands[2], operands[3]);
11623   if (GET_CODE (operands[4]) == SCRATCH)
11624     operands[4] = gen_reg_rtx (<MODE>mode);
11626   [(set (attr "length")
11627         (if_then_else (match_test "operands[2] == const0_rtx")
11628                       (const_string "8")
11629                       (const_string "12")))])
11631 (define_insn_and_split "*neg_eq_<mode>"
11632   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11633         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11634                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11635    (clobber (match_scratch:P 3 "=r"))
11636    (clobber (match_scratch:P 4 "=r"))
11637    (clobber (reg:P CA_REGNO))]
11638   ""
11639   "#"
11640   ""
11641   [(parallel [(set (match_dup 4)
11642                    (plus:P (match_dup 3)
11643                            (const_int -1)))
11644               (set (reg:P CA_REGNO)
11645                    (ne:P (match_dup 3)
11646                          (const_int 0)))])
11647    (parallel [(set (match_dup 0)
11648                    (plus:P (reg:P CA_REGNO)
11649                            (const_int -1)))
11650               (clobber (reg:P CA_REGNO))])]
11652   operands[3] = rs6000_emit_eqne (<MODE>mode,
11653                                   operands[1], operands[2], operands[3]);
11655   if (GET_CODE (operands[4]) == SCRATCH)
11656     operands[4] = gen_reg_rtx (<MODE>mode);
11658   [(set (attr "length")
11659         (if_then_else (match_test "operands[2] == const0_rtx")
11660                       (const_string "8")
11661                       (const_string "12")))])
11663 (define_insn_and_split "*neg_ne_<mode>"
11664   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11665         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11666                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11667    (clobber (match_scratch:P 3 "=r"))
11668    (clobber (match_scratch:P 4 "=r"))
11669    (clobber (reg:P CA_REGNO))]
11670   ""
11671   "#"
11672   ""
11673   [(parallel [(set (match_dup 4)
11674                    (neg:P (match_dup 3)))
11675               (set (reg:P CA_REGNO)
11676                    (eq:P (match_dup 3)
11677                          (const_int 0)))])
11678    (parallel [(set (match_dup 0)
11679                    (plus:P (reg:P CA_REGNO)
11680                            (const_int -1)))
11681               (clobber (reg:P CA_REGNO))])]
11683   operands[3] = rs6000_emit_eqne (<MODE>mode,
11684                                   operands[1], operands[2], operands[3]);
11686   if (GET_CODE (operands[4]) == SCRATCH)
11687     operands[4] = gen_reg_rtx (<MODE>mode);
11689   [(set (attr "length")
11690         (if_then_else (match_test "operands[2] == const0_rtx")
11691                       (const_string "8")
11692                       (const_string "12")))])
11694 (define_insn_and_split "*plus_eq_<mode>"
11695   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11696         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11697                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11698                 (match_operand:P 3 "gpc_reg_operand" "r")))
11699    (clobber (match_scratch:P 4 "=r"))
11700    (clobber (match_scratch:P 5 "=r"))
11701    (clobber (reg:P CA_REGNO))]
11702   ""
11703   "#"
11704   ""
11705   [(parallel [(set (match_dup 5)
11706                    (neg:P (match_dup 4)))
11707               (set (reg:P CA_REGNO)
11708                    (eq:P (match_dup 4)
11709                          (const_int 0)))])
11710    (parallel [(set (match_dup 0)
11711                    (plus:P (match_dup 3)
11712                            (reg:P CA_REGNO)))
11713               (clobber (reg:P CA_REGNO))])]
11715   operands[4] = rs6000_emit_eqne (<MODE>mode,
11716                                   operands[1], operands[2], operands[4]);
11718   if (GET_CODE (operands[5]) == SCRATCH)
11719     operands[5] = gen_reg_rtx (<MODE>mode);
11721   [(set (attr "length")
11722         (if_then_else (match_test "operands[2] == const0_rtx")
11723                       (const_string "8")
11724                       (const_string "12")))])
11726 (define_insn_and_split "*plus_ne_<mode>"
11727   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11728         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11729                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11730                 (match_operand:P 3 "gpc_reg_operand" "r")))
11731    (clobber (match_scratch:P 4 "=r"))
11732    (clobber (match_scratch:P 5 "=r"))
11733    (clobber (reg:P CA_REGNO))]
11734   ""
11735   "#"
11736   ""
11737   [(parallel [(set (match_dup 5)
11738                    (plus:P (match_dup 4)
11739                            (const_int -1)))
11740               (set (reg:P CA_REGNO)
11741                    (ne:P (match_dup 4)
11742                          (const_int 0)))])
11743    (parallel [(set (match_dup 0)
11744                    (plus:P (match_dup 3)
11745                            (reg:P CA_REGNO)))
11746               (clobber (reg:P CA_REGNO))])]
11748   operands[4] = rs6000_emit_eqne (<MODE>mode,
11749                                   operands[1], operands[2], operands[4]);
11751   if (GET_CODE (operands[5]) == SCRATCH)
11752     operands[5] = gen_reg_rtx (<MODE>mode);
11754   [(set (attr "length")
11755         (if_then_else (match_test "operands[2] == const0_rtx")
11756                       (const_string "8")
11757                       (const_string "12")))])
11759 (define_insn_and_split "*minus_eq_<mode>"
11760   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11761         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11762                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11763                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11764    (clobber (match_scratch:P 4 "=r"))
11765    (clobber (match_scratch:P 5 "=r"))
11766    (clobber (reg:P CA_REGNO))]
11767   ""
11768   "#"
11769   ""
11770   [(parallel [(set (match_dup 5)
11771                    (plus:P (match_dup 4)
11772                            (const_int -1)))
11773               (set (reg:P CA_REGNO)
11774                    (ne:P (match_dup 4)
11775                          (const_int 0)))])
11776    (parallel [(set (match_dup 0)
11777                    (plus:P (plus:P (match_dup 3)
11778                                    (reg:P CA_REGNO))
11779                            (const_int -1)))
11780               (clobber (reg:P CA_REGNO))])]
11782   operands[4] = rs6000_emit_eqne (<MODE>mode,
11783                                   operands[1], operands[2], operands[4]);
11785   if (GET_CODE (operands[5]) == SCRATCH)
11786     operands[5] = gen_reg_rtx (<MODE>mode);
11788   [(set (attr "length")
11789         (if_then_else (match_test "operands[2] == const0_rtx")
11790                       (const_string "8")
11791                       (const_string "12")))])
11793 (define_insn_and_split "*minus_ne_<mode>"
11794   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11795         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11796                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11797                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11798    (clobber (match_scratch:P 4 "=r"))
11799    (clobber (match_scratch:P 5 "=r"))
11800    (clobber (reg:P CA_REGNO))]
11801   ""
11802   "#"
11803   ""
11804   [(parallel [(set (match_dup 5)
11805                    (neg:P (match_dup 4)))
11806               (set (reg:P CA_REGNO)
11807                    (eq:P (match_dup 4)
11808                          (const_int 0)))])
11809    (parallel [(set (match_dup 0)
11810                    (plus:P (plus:P (match_dup 3)
11811                                    (reg:P CA_REGNO))
11812                            (const_int -1)))
11813               (clobber (reg:P CA_REGNO))])]
11815   operands[4] = rs6000_emit_eqne (<MODE>mode,
11816                                   operands[1], operands[2], operands[4]);
11818   if (GET_CODE (operands[5]) == SCRATCH)
11819     operands[5] = gen_reg_rtx (<MODE>mode);
11821   [(set (attr "length")
11822         (if_then_else (match_test "operands[2] == const0_rtx")
11823                       (const_string "8")
11824                       (const_string "12")))])
11826 (define_insn_and_split "*eqsi3_ext<mode>"
11827   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11828         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11829                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11830    (clobber (match_scratch:SI 3 "=r"))
11831    (clobber (match_scratch:SI 4 "=r"))]
11832   ""
11833   "#"
11834   ""
11835   [(set (match_dup 4)
11836         (clz:SI (match_dup 3)))
11837    (set (match_dup 0)
11838         (zero_extend:EXTSI
11839           (lshiftrt:SI (match_dup 4)
11840                        (const_int 5))))]
11842   operands[3] = rs6000_emit_eqne (SImode,
11843                                   operands[1], operands[2], operands[3]);
11845   if (GET_CODE (operands[4]) == SCRATCH)
11846     operands[4] = gen_reg_rtx (SImode);
11848   [(set (attr "length")
11849         (if_then_else (match_test "operands[2] == const0_rtx")
11850                       (const_string "8")
11851                       (const_string "12")))])
11853 (define_insn_and_split "*nesi3_ext<mode>"
11854   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11855         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11856                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11857    (clobber (match_scratch:SI 3 "=r"))
11858    (clobber (match_scratch:SI 4 "=r"))
11859    (clobber (match_scratch:EXTSI 5 "=r"))]
11860   ""
11861   "#"
11862   ""
11863   [(set (match_dup 4)
11864         (clz:SI (match_dup 3)))
11865    (set (match_dup 5)
11866         (zero_extend:EXTSI
11867           (lshiftrt:SI (match_dup 4)
11868                        (const_int 5))))
11869    (set (match_dup 0)
11870         (xor:EXTSI (match_dup 5)
11871                    (const_int 1)))]
11873   operands[3] = rs6000_emit_eqne (SImode,
11874                                   operands[1], operands[2], operands[3]);
11876   if (GET_CODE (operands[4]) == SCRATCH)
11877     operands[4] = gen_reg_rtx (SImode);
11878   if (GET_CODE (operands[5]) == SCRATCH)
11879     operands[5] = gen_reg_rtx (<MODE>mode);
11881   [(set (attr "length")
11882         (if_then_else (match_test "operands[2] == const0_rtx")
11883                       (const_string "12")
11884                       (const_string "16")))])
11886 ;; Define both directions of branch and return.  If we need a reload
11887 ;; register, we'd rather use CR0 since it is much easier to copy a
11888 ;; register CC value to there.
11890 (define_insn ""
11891   [(set (pc)
11892         (if_then_else (match_operator 1 "branch_comparison_operator"
11893                                       [(match_operand 2
11894                                                       "cc_reg_operand" "y")
11895                                        (const_int 0)])
11896                       (label_ref (match_operand 0 "" ""))
11897                       (pc)))]
11898   ""
11899   "*
11901   return output_cbranch (operands[1], \"%l0\", 0, insn);
11903   [(set_attr "type" "branch")])
11905 (define_insn ""
11906   [(set (pc)
11907         (if_then_else (match_operator 0 "branch_comparison_operator"
11908                                       [(match_operand 1
11909                                                       "cc_reg_operand" "y")
11910                                        (const_int 0)])
11911                       (any_return)
11912                       (pc)))]
11913   "<return_pred>"
11914   "*
11916   return output_cbranch (operands[0], NULL, 0, insn);
11918   [(set_attr "type" "jmpreg")
11919    (set_attr "length" "4")])
11921 (define_insn ""
11922   [(set (pc)
11923         (if_then_else (match_operator 1 "branch_comparison_operator"
11924                                       [(match_operand 2
11925                                                       "cc_reg_operand" "y")
11926                                        (const_int 0)])
11927                       (pc)
11928                       (label_ref (match_operand 0 "" ""))))]
11929   ""
11930   "*
11932   return output_cbranch (operands[1], \"%l0\", 1, insn);
11934   [(set_attr "type" "branch")])
11936 (define_insn ""
11937   [(set (pc)
11938         (if_then_else (match_operator 0 "branch_comparison_operator"
11939                                       [(match_operand 1
11940                                                       "cc_reg_operand" "y")
11941                                        (const_int 0)])
11942                       (pc)
11943                       (any_return)))]
11944   "<return_pred>"
11945   "*
11947   return output_cbranch (operands[0], NULL, 1, insn);
11949   [(set_attr "type" "jmpreg")
11950    (set_attr "length" "4")])
11952 ;; Logic on condition register values.
11954 ; This pattern matches things like
11955 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11956 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
11957 ;                                  (const_int 1)))
11958 ; which are generated by the branch logic.
11959 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11961 (define_insn "*cceq_ior_compare"
11962   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11963         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11964                         [(match_operator:SI 2
11965                                       "branch_positive_comparison_operator"
11966                                       [(match_operand 3
11967                                                       "cc_reg_operand" "y,y")
11968                                        (const_int 0)])
11969                          (match_operator:SI 4
11970                                       "branch_positive_comparison_operator"
11971                                       [(match_operand 5
11972                                                       "cc_reg_operand" "0,y")
11973                                        (const_int 0)])])
11974                       (const_int 1)))]
11975   ""
11976   "cr%q1 %E0,%j2,%j4"
11977   [(set_attr "type" "cr_logical,delayed_cr")])
11979 ; Why is the constant -1 here, but 1 in the previous pattern?
11980 ; Because ~1 has all but the low bit set.
11981 (define_insn ""
11982   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11983         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11984                         [(not:SI (match_operator:SI 2
11985                                       "branch_positive_comparison_operator"
11986                                       [(match_operand 3
11987                                                       "cc_reg_operand" "y,y")
11988                                        (const_int 0)]))
11989                          (match_operator:SI 4
11990                                 "branch_positive_comparison_operator"
11991                                 [(match_operand 5
11992                                                 "cc_reg_operand" "0,y")
11993                                  (const_int 0)])])
11994                       (const_int -1)))]
11995   ""
11996   "cr%q1 %E0,%j2,%j4"
11997   [(set_attr "type" "cr_logical,delayed_cr")])
11999 (define_insn "*cceq_rev_compare"
12000   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12001         (compare:CCEQ (match_operator:SI 1
12002                                       "branch_positive_comparison_operator"
12003                                       [(match_operand 2
12004                                                       "cc_reg_operand" "0,y")
12005                                        (const_int 0)])
12006                       (const_int 0)))]
12007   ""
12008   "crnot %E0,%j1"
12009   [(set_attr "type" "cr_logical,delayed_cr")])
12011 ;; If we are comparing the result of two comparisons, this can be done
12012 ;; using creqv or crxor.
12014 (define_insn_and_split ""
12015   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12016         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12017                               [(match_operand 2 "cc_reg_operand" "y")
12018                                (const_int 0)])
12019                       (match_operator 3 "branch_comparison_operator"
12020                               [(match_operand 4 "cc_reg_operand" "y")
12021                                (const_int 0)])))]
12022   ""
12023   "#"
12024   ""
12025   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12026                                     (match_dup 5)))]
12027   "
12029   int positive_1, positive_2;
12031   positive_1 = branch_positive_comparison_operator (operands[1],
12032                                                     GET_MODE (operands[1]));
12033   positive_2 = branch_positive_comparison_operator (operands[3],
12034                                                     GET_MODE (operands[3]));
12036   if (! positive_1)
12037     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12038                                                             GET_CODE (operands[1])),
12039                                   SImode,
12040                                   operands[2], const0_rtx);
12041   else if (GET_MODE (operands[1]) != SImode)
12042     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12043                                   operands[2], const0_rtx);
12045   if (! positive_2)
12046     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12047                                                             GET_CODE (operands[3])),
12048                                   SImode,
12049                                   operands[4], const0_rtx);
12050   else if (GET_MODE (operands[3]) != SImode)
12051     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12052                                   operands[4], const0_rtx);
12054   if (positive_1 == positive_2)
12055     {
12056       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12057       operands[5] = constm1_rtx;
12058     }
12059   else
12060     {
12061       operands[5] = const1_rtx;
12062     }
12065 ;; Unconditional branch and return.
12067 (define_insn "jump"
12068   [(set (pc)
12069         (label_ref (match_operand 0 "" "")))]
12070   ""
12071   "b %l0"
12072   [(set_attr "type" "branch")])
12074 (define_insn "<return_str>return"
12075   [(any_return)]
12076   "<return_pred>"
12077   "blr"
12078   [(set_attr "type" "jmpreg")])
12080 (define_expand "indirect_jump"
12081   [(set (pc) (match_operand 0 "register_operand" ""))])
12083 (define_insn "*indirect_jump<mode>"
12084   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12085   ""
12086   "@
12087    bctr
12088    blr"
12089   [(set_attr "type" "jmpreg")])
12091 ;; Table jump for switch statements:
12092 (define_expand "tablejump"
12093   [(use (match_operand 0 "" ""))
12094    (use (label_ref (match_operand 1 "" "")))]
12095   ""
12096   "
12098   if (TARGET_32BIT)
12099     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12100   else
12101     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12102   DONE;
12105 (define_expand "tablejumpsi"
12106   [(set (match_dup 3)
12107         (plus:SI (match_operand:SI 0 "" "")
12108                  (match_dup 2)))
12109    (parallel [(set (pc) (match_dup 3))
12110               (use (label_ref (match_operand 1 "" "")))])]
12111   "TARGET_32BIT"
12112   "
12113 { operands[0] = force_reg (SImode, operands[0]);
12114   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12115   operands[3] = gen_reg_rtx (SImode);
12118 (define_expand "tablejumpdi"
12119   [(set (match_dup 4)
12120         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12121    (set (match_dup 3)
12122         (plus:DI (match_dup 4)
12123                  (match_dup 2)))
12124    (parallel [(set (pc) (match_dup 3))
12125               (use (label_ref (match_operand 1 "" "")))])]
12126   "TARGET_64BIT"
12127   "
12128 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12129   operands[3] = gen_reg_rtx (DImode);
12130   operands[4] = gen_reg_rtx (DImode);
12133 (define_insn "*tablejump<mode>_internal1"
12134   [(set (pc)
12135         (match_operand:P 0 "register_operand" "c,*l"))
12136    (use (label_ref (match_operand 1 "" "")))]
12137   ""
12138   "@
12139    bctr
12140    blr"
12141   [(set_attr "type" "jmpreg")])
12143 (define_insn "nop"
12144   [(unspec [(const_int 0)] UNSPEC_NOP)]
12145   ""
12146   "nop")
12148 (define_insn "group_ending_nop"
12149   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12150   ""
12151   "*
12153   if (rs6000_cpu_attr == CPU_POWER6)
12154     return \"ori 1,1,0\";
12155   return \"ori 2,2,0\";
12158 ;; Define the subtract-one-and-jump insns, starting with the template
12159 ;; so loop.c knows what to generate.
12161 (define_expand "doloop_end"
12162   [(use (match_operand 0 "" ""))        ; loop pseudo
12163    (use (match_operand 1 "" ""))]       ; label
12164   ""
12165   "
12167   if (TARGET_64BIT)
12168     {
12169       if (GET_MODE (operands[0]) != DImode)
12170         FAIL;
12171       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12172     }
12173   else
12174     {
12175       if (GET_MODE (operands[0]) != SImode)
12176         FAIL;
12177       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12178     }
12179   DONE;
12182 (define_expand "ctr<mode>"
12183   [(parallel [(set (pc)
12184                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12185                                      (const_int 1))
12186                                  (label_ref (match_operand 1 "" ""))
12187                                  (pc)))
12188               (set (match_dup 0)
12189                    (plus:P (match_dup 0)
12190                             (const_int -1)))
12191               (unspec [(const_int 0)] UNSPEC_DOLOOP)
12192               (clobber (match_scratch:CC 2 ""))
12193               (clobber (match_scratch:P 3 ""))])]
12194   ""
12195   "")
12197 ;; We need to be able to do this for any operand, including MEM, or we
12198 ;; will cause reload to blow up since we don't allow output reloads on
12199 ;; JUMP_INSNs.
12200 ;; For the length attribute to be calculated correctly, the
12201 ;; label MUST be operand 0.
12202 ;; The UNSPEC is present to prevent combine creating this pattern.
12204 (define_insn "*ctr<mode>_internal1"
12205   [(set (pc)
12206         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12207                           (const_int 1))
12208                       (label_ref (match_operand 0 "" ""))
12209                       (pc)))
12210    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12211         (plus:P (match_dup 1)
12212                  (const_int -1)))
12213    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12214    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12215    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12216   ""
12217   "*
12219   if (which_alternative != 0)
12220     return \"#\";
12221   else if (get_attr_length (insn) == 4)
12222     return \"bdnz %l0\";
12223   else
12224     return \"bdz $+8\;b %l0\";
12226   [(set_attr "type" "branch")
12227    (set_attr "length" "*,16,20,20")])
12229 (define_insn "*ctr<mode>_internal2"
12230   [(set (pc)
12231         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12232                           (const_int 1))
12233                       (pc)
12234                       (label_ref (match_operand 0 "" ""))))
12235    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12236         (plus:P (match_dup 1)
12237                  (const_int -1)))
12238    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12239    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12240    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12241   ""
12242   "*
12244   if (which_alternative != 0)
12245     return \"#\";
12246   else if (get_attr_length (insn) == 4)
12247     return \"bdz %l0\";
12248   else
12249     return \"bdnz $+8\;b %l0\";
12251   [(set_attr "type" "branch")
12252    (set_attr "length" "*,16,20,20")])
12254 ;; Similar but use EQ
12256 (define_insn "*ctr<mode>_internal5"
12257   [(set (pc)
12258         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12259                           (const_int 1))
12260                       (label_ref (match_operand 0 "" ""))
12261                       (pc)))
12262    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12263         (plus:P (match_dup 1)
12264                  (const_int -1)))
12265    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12266    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12267    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12268   ""
12269   "*
12271   if (which_alternative != 0)
12272     return \"#\";
12273   else if (get_attr_length (insn) == 4)
12274     return \"bdz %l0\";
12275   else
12276     return \"bdnz $+8\;b %l0\";
12278   [(set_attr "type" "branch")
12279    (set_attr "length" "*,16,20,20")])
12281 (define_insn "*ctr<mode>_internal6"
12282   [(set (pc)
12283         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12284                           (const_int 1))
12285                       (pc)
12286                       (label_ref (match_operand 0 "" ""))))
12287    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12288         (plus:P (match_dup 1)
12289                  (const_int -1)))
12290    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12291    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12292    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12293   ""
12294   "*
12296   if (which_alternative != 0)
12297     return \"#\";
12298   else if (get_attr_length (insn) == 4)
12299     return \"bdnz %l0\";
12300   else
12301     return \"bdz $+8\;b %l0\";
12303   [(set_attr "type" "branch")
12304    (set_attr "length" "*,16,20,20")])
12306 ;; Now the splitters if we could not allocate the CTR register
12308 (define_split
12309   [(set (pc)
12310         (if_then_else (match_operator 2 "comparison_operator"
12311                                       [(match_operand:P 1 "gpc_reg_operand" "")
12312                                        (const_int 1)])
12313                       (match_operand 5 "" "")
12314                       (match_operand 6 "" "")))
12315    (set (match_operand:P 0 "int_reg_operand" "")
12316         (plus:P (match_dup 1) (const_int -1)))
12317    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12318    (clobber (match_scratch:CC 3 ""))
12319    (clobber (match_scratch:P 4 ""))]
12320   "reload_completed"
12321   [(set (match_dup 3)
12322         (compare:CC (match_dup 1)
12323                     (const_int 1)))
12324    (set (match_dup 0)
12325         (plus:P (match_dup 1)
12326                 (const_int -1)))
12327    (set (pc) (if_then_else (match_dup 7)
12328                            (match_dup 5)
12329                            (match_dup 6)))]
12330   "
12331 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12332                                 operands[3], const0_rtx); }")
12334 (define_split
12335   [(set (pc)
12336         (if_then_else (match_operator 2 "comparison_operator"
12337                                       [(match_operand:P 1 "gpc_reg_operand" "")
12338                                        (const_int 1)])
12339                       (match_operand 5 "" "")
12340                       (match_operand 6 "" "")))
12341    (set (match_operand:P 0 "nonimmediate_operand" "")
12342         (plus:P (match_dup 1) (const_int -1)))
12343    (unspec [(const_int 0)] UNSPEC_DOLOOP)
12344    (clobber (match_scratch:CC 3 ""))
12345    (clobber (match_scratch:P 4 ""))]
12346   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12347   [(set (match_dup 3)
12348         (compare:CC (match_dup 1)
12349                     (const_int 1)))
12350    (set (match_dup 4)
12351         (plus:P (match_dup 1)
12352                 (const_int -1)))
12353    (set (match_dup 0)
12354         (match_dup 4))
12355    (set (pc) (if_then_else (match_dup 7)
12356                            (match_dup 5)
12357                            (match_dup 6)))]
12358   "
12359 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12360                                 operands[3], const0_rtx); }")
12362 (define_insn "trap"
12363   [(trap_if (const_int 1) (const_int 0))]
12364   ""
12365   "trap"
12366   [(set_attr "type" "trap")])
12368 (define_expand "ctrap<mode>4"
12369   [(trap_if (match_operator 0 "ordered_comparison_operator"
12370                             [(match_operand:GPR 1 "register_operand")
12371                              (match_operand:GPR 2 "reg_or_short_operand")])
12372             (match_operand 3 "zero_constant" ""))]
12373   ""
12374   "")
12376 (define_insn ""
12377   [(trap_if (match_operator 0 "ordered_comparison_operator"
12378                             [(match_operand:GPR 1 "register_operand" "r")
12379                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12380             (const_int 0))]
12381   ""
12382   "t<wd>%V0%I2 %1,%2"
12383   [(set_attr "type" "trap")])
12385 ;; Insns related to generating the function prologue and epilogue.
12387 (define_expand "prologue"
12388   [(use (const_int 0))]
12389   ""
12391   rs6000_emit_prologue ();
12392   if (!TARGET_SCHED_PROLOG)
12393     emit_insn (gen_blockage ());
12394   DONE;
12397 (define_insn "*movesi_from_cr_one"
12398   [(match_parallel 0 "mfcr_operation"
12399                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12400                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12401                                      (match_operand 3 "immediate_operand" "n")]
12402                           UNSPEC_MOVESI_FROM_CR))])]
12403   "TARGET_MFCRF"
12404   "*
12406   int mask = 0;
12407   int i;
12408   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12409   {
12410     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12411     operands[4] = GEN_INT (mask);
12412     output_asm_insn (\"mfcr %1,%4\", operands);
12413   }
12414   return \"\";
12416   [(set_attr "type" "mfcrf")])
12418 (define_insn "movesi_from_cr"
12419   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12420         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12421                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12422                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12423                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12424                    UNSPEC_MOVESI_FROM_CR))]
12425   ""
12426   "mfcr %0"
12427   [(set_attr "type" "mfcr")])
12429 (define_insn "*crsave"
12430   [(match_parallel 0 "crsave_operation"
12431                    [(set (match_operand:SI 1 "memory_operand" "=m")
12432                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12433   ""
12434   "stw %2,%1"
12435   [(set_attr "type" "store")])
12437 (define_insn "*stmw"
12438   [(match_parallel 0 "stmw_operation"
12439                    [(set (match_operand:SI 1 "memory_operand" "=m")
12440                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12441   "TARGET_MULTIPLE"
12442   "stmw %2,%1"
12443   [(set_attr "type" "store")
12444    (set_attr "update" "yes")
12445    (set_attr "indexed" "yes")])
12447 ; The following comment applies to:
12448 ;     save_gpregs_*
12449 ;     save_fpregs_*
12450 ;     restore_gpregs*
12451 ;     return_and_restore_gpregs*
12452 ;     return_and_restore_fpregs*
12453 ;     return_and_restore_fpregs_aix*
12455 ; The out-of-line save / restore functions expects one input argument.
12456 ; Since those are not standard call_insn's, we must avoid using
12457 ; MATCH_OPERAND for that argument. That way the register rename
12458 ; optimization will not try to rename this register.
12459 ; Each pattern is repeated for each possible register number used in 
12460 ; various ABIs (r11, r1, and for some functions r12)
12462 (define_insn "*save_gpregs_<mode>_r11"
12463   [(match_parallel 0 "any_parallel_operand"
12464                    [(clobber (reg:P 65))
12465                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12466                     (use (reg:P 11))
12467                     (set (match_operand:P 2 "memory_operand" "=m")
12468                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12469   ""
12470   "bl %1"
12471   [(set_attr "type" "branch")
12472    (set_attr "length" "4")])
12474 (define_insn "*save_gpregs_<mode>_r12"
12475   [(match_parallel 0 "any_parallel_operand"
12476                    [(clobber (reg:P 65))
12477                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12478                     (use (reg:P 12))
12479                     (set (match_operand:P 2 "memory_operand" "=m")
12480                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12481   ""
12482   "bl %1"
12483   [(set_attr "type" "branch")
12484    (set_attr "length" "4")])
12486 (define_insn "*save_gpregs_<mode>_r1"
12487   [(match_parallel 0 "any_parallel_operand"
12488                    [(clobber (reg:P 65))
12489                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12490                     (use (reg:P 1))
12491                     (set (match_operand:P 2 "memory_operand" "=m")
12492                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12493   ""
12494   "bl %1"
12495   [(set_attr "type" "branch")
12496    (set_attr "length" "4")])
12498 (define_insn "*save_fpregs_<mode>_r11"
12499   [(match_parallel 0 "any_parallel_operand"
12500                    [(clobber (reg:P 65))
12501                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12502                     (use (reg:P 11))
12503                     (set (match_operand:DF 2 "memory_operand" "=m")
12504                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12505   ""
12506   "bl %1"
12507   [(set_attr "type" "branch")
12508    (set_attr "length" "4")])
12510 (define_insn "*save_fpregs_<mode>_r12"
12511   [(match_parallel 0 "any_parallel_operand"
12512                    [(clobber (reg:P 65))
12513                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12514                     (use (reg:P 12))
12515                     (set (match_operand:DF 2 "memory_operand" "=m")
12516                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12517   ""
12518   "bl %1"
12519   [(set_attr "type" "branch")
12520    (set_attr "length" "4")])
12522 (define_insn "*save_fpregs_<mode>_r1"
12523   [(match_parallel 0 "any_parallel_operand"
12524                    [(clobber (reg:P 65))
12525                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12526                     (use (reg:P 1))
12527                     (set (match_operand:DF 2 "memory_operand" "=m")
12528                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12529   ""
12530   "bl %1"
12531   [(set_attr "type" "branch")
12532    (set_attr "length" "4")])
12534 ; This is to explain that changes to the stack pointer should
12535 ; not be moved over loads from or stores to stack memory.
12536 (define_insn "stack_tie"
12537   [(match_parallel 0 "tie_operand"
12538                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12539   ""
12540   ""
12541   [(set_attr "length" "0")])
12543 (define_expand "epilogue"
12544   [(use (const_int 0))]
12545   ""
12547   if (!TARGET_SCHED_PROLOG)
12548     emit_insn (gen_blockage ());
12549   rs6000_emit_epilogue (FALSE);
12550   DONE;
12553 ; On some processors, doing the mtcrf one CC register at a time is
12554 ; faster (like on the 604e).  On others, doing them all at once is
12555 ; faster; for instance, on the 601 and 750.
12557 (define_expand "movsi_to_cr_one"
12558   [(set (match_operand:CC 0 "cc_reg_operand" "")
12559         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12560                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12561   ""
12562   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12564 (define_insn "*movsi_to_cr"
12565   [(match_parallel 0 "mtcrf_operation"
12566                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12567                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12568                                      (match_operand 3 "immediate_operand" "n")]
12569                                     UNSPEC_MOVESI_TO_CR))])]
12570  ""
12571  "*
12573   int mask = 0;
12574   int i;
12575   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12576     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12577   operands[4] = GEN_INT (mask);
12578   return \"mtcrf %4,%2\";
12580   [(set_attr "type" "mtcr")])
12582 (define_insn "*mtcrfsi"
12583   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12584         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12585                     (match_operand 2 "immediate_operand" "n")]
12586                    UNSPEC_MOVESI_TO_CR))]
12587   "GET_CODE (operands[0]) == REG
12588    && CR_REGNO_P (REGNO (operands[0]))
12589    && GET_CODE (operands[2]) == CONST_INT
12590    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12591   "mtcrf %R0,%1"
12592   [(set_attr "type" "mtcr")])
12594 ; The load-multiple instructions have similar properties.
12595 ; Note that "load_multiple" is a name known to the machine-independent
12596 ; code that actually corresponds to the PowerPC load-string.
12598 (define_insn "*lmw"
12599   [(match_parallel 0 "lmw_operation"
12600                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12601                          (match_operand:SI 2 "memory_operand" "m"))])]
12602   "TARGET_MULTIPLE"
12603   "lmw %1,%2"
12604   [(set_attr "type" "load")
12605    (set_attr "update" "yes")
12606    (set_attr "indexed" "yes")
12607    (set_attr "cell_micro" "always")])
12609 (define_insn "*return_internal_<mode>"
12610   [(simple_return)
12611    (use (match_operand:P 0 "register_operand" "lc"))]
12612   ""
12613   "b%T0"
12614   [(set_attr "type" "jmpreg")])
12616 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12617 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12619 ; The following comment applies to:
12620 ;     save_gpregs_*
12621 ;     save_fpregs_*
12622 ;     restore_gpregs*
12623 ;     return_and_restore_gpregs*
12624 ;     return_and_restore_fpregs*
12625 ;     return_and_restore_fpregs_aix*
12627 ; The out-of-line save / restore functions expects one input argument.
12628 ; Since those are not standard call_insn's, we must avoid using
12629 ; MATCH_OPERAND for that argument. That way the register rename
12630 ; optimization will not try to rename this register.
12631 ; Each pattern is repeated for each possible register number used in 
12632 ; various ABIs (r11, r1, and for some functions r12)
12634 (define_insn "*restore_gpregs_<mode>_r11"
12635  [(match_parallel 0 "any_parallel_operand"
12636                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12637                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12638                    (use (reg:P 11))
12639                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12640                         (match_operand:P 4 "memory_operand" "m"))])]
12641  ""
12642  "bl %2"
12643  [(set_attr "type" "branch")
12644   (set_attr "length" "4")])
12646 (define_insn "*restore_gpregs_<mode>_r12"
12647  [(match_parallel 0 "any_parallel_operand"
12648                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12649                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12650                    (use (reg:P 12))
12651                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12652                         (match_operand:P 4 "memory_operand" "m"))])]
12653  ""
12654  "bl %2"
12655  [(set_attr "type" "branch")
12656   (set_attr "length" "4")])
12658 (define_insn "*restore_gpregs_<mode>_r1"
12659  [(match_parallel 0 "any_parallel_operand"
12660                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12661                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12662                    (use (reg:P 1))
12663                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12664                         (match_operand:P 4 "memory_operand" "m"))])]
12665  ""
12666  "bl %2"
12667  [(set_attr "type" "branch")
12668   (set_attr "length" "4")])
12670 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12671  [(match_parallel 0 "any_parallel_operand"
12672                   [(return)
12673                    (clobber (match_operand:P 1 "register_operand" "=l"))
12674                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12675                    (use (reg:P 11))
12676                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12677                         (match_operand:P 4 "memory_operand" "m"))])]
12678  ""
12679  "b %2"
12680  [(set_attr "type" "branch")
12681   (set_attr "length" "4")])
12683 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12684  [(match_parallel 0 "any_parallel_operand"
12685                   [(return)
12686                    (clobber (match_operand:P 1 "register_operand" "=l"))
12687                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12688                    (use (reg:P 12))
12689                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12690                         (match_operand:P 4 "memory_operand" "m"))])]
12691  ""
12692  "b %2"
12693  [(set_attr "type" "branch")
12694   (set_attr "length" "4")])
12696 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12697  [(match_parallel 0 "any_parallel_operand"
12698                   [(return)
12699                    (clobber (match_operand:P 1 "register_operand" "=l"))
12700                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12701                    (use (reg:P 1))
12702                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12703                         (match_operand:P 4 "memory_operand" "m"))])]
12704  ""
12705  "b %2"
12706  [(set_attr "type" "branch")
12707   (set_attr "length" "4")])
12709 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12710  [(match_parallel 0 "any_parallel_operand"
12711                   [(return)
12712                    (clobber (match_operand:P 1 "register_operand" "=l"))
12713                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12714                    (use (reg:P 11))
12715                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12716                         (match_operand:DF 4 "memory_operand" "m"))])]
12717  ""
12718  "b %2"
12719  [(set_attr "type" "branch")
12720   (set_attr "length" "4")])
12722 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12723  [(match_parallel 0 "any_parallel_operand"
12724                   [(return)
12725                    (clobber (match_operand:P 1 "register_operand" "=l"))
12726                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12727                    (use (reg:P 12))
12728                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12729                         (match_operand:DF 4 "memory_operand" "m"))])]
12730  ""
12731  "b %2"
12732  [(set_attr "type" "branch")
12733   (set_attr "length" "4")])
12735 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12736  [(match_parallel 0 "any_parallel_operand"
12737                   [(return)
12738                    (clobber (match_operand:P 1 "register_operand" "=l"))
12739                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12740                    (use (reg:P 1))
12741                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12742                         (match_operand:DF 4 "memory_operand" "m"))])]
12743  ""
12744  "b %2"
12745  [(set_attr "type" "branch")
12746   (set_attr "length" "4")])
12748 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12749  [(match_parallel 0 "any_parallel_operand"
12750                   [(return)
12751                    (use (match_operand:P 1 "register_operand" "l"))
12752                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12753                    (use (reg:P 11))
12754                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12755                         (match_operand:DF 4 "memory_operand" "m"))])]
12756  ""
12757  "b %2"
12758  [(set_attr "type" "branch")
12759   (set_attr "length" "4")])
12761 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12762  [(match_parallel 0 "any_parallel_operand"
12763                   [(return)
12764                    (use (match_operand:P 1 "register_operand" "l"))
12765                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12766                    (use (reg:P 1))
12767                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12768                         (match_operand:DF 4 "memory_operand" "m"))])]
12769  ""
12770  "b %2"
12771  [(set_attr "type" "branch")
12772   (set_attr "length" "4")])
12774 ; This is used in compiling the unwind routines.
12775 (define_expand "eh_return"
12776   [(use (match_operand 0 "general_operand" ""))]
12777   ""
12778   "
12780   if (TARGET_32BIT)
12781     emit_insn (gen_eh_set_lr_si (operands[0]));
12782   else
12783     emit_insn (gen_eh_set_lr_di (operands[0]));
12784   DONE;
12787 ; We can't expand this before we know where the link register is stored.
12788 (define_insn "eh_set_lr_<mode>"
12789   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12790                     UNSPECV_EH_RR)
12791    (clobber (match_scratch:P 1 "=&b"))]
12792   ""
12793   "#")
12795 (define_split
12796   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12797    (clobber (match_scratch 1 ""))]
12798   "reload_completed"
12799   [(const_int 0)]
12800   "
12802   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12803   DONE;
12806 (define_insn "prefetch"
12807   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12808              (match_operand:SI 1 "const_int_operand" "n")
12809              (match_operand:SI 2 "const_int_operand" "n"))]
12810   ""
12811   "*
12813   if (GET_CODE (operands[0]) == REG)
12814     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12815   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12817   [(set_attr "type" "load")])
12819 ;; Handle -fsplit-stack.
12821 (define_expand "split_stack_prologue"
12822   [(const_int 0)]
12823   ""
12825   rs6000_expand_split_stack_prologue ();
12826   DONE;
12829 (define_expand "load_split_stack_limit"
12830   [(set (match_operand 0)
12831         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12832   ""
12834   emit_insn (gen_rtx_SET (operands[0],
12835                           gen_rtx_UNSPEC (Pmode,
12836                                           gen_rtvec (1, const0_rtx),
12837                                           UNSPEC_STACK_CHECK)));
12838   DONE;
12841 (define_insn "load_split_stack_limit_di"
12842   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12843         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12844   "TARGET_64BIT"
12845   "ld %0,-0x7040(13)"
12846   [(set_attr "type" "load")
12847    (set_attr "update" "no")
12848    (set_attr "indexed" "no")])
12850 (define_insn "load_split_stack_limit_si"
12851   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12852         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12853   "!TARGET_64BIT"
12854   "lwz %0,-0x7020(2)"
12855   [(set_attr "type" "load")
12856    (set_attr "update" "no")
12857    (set_attr "indexed" "no")])
12859 ;; A return instruction which the middle-end doesn't see.
12860 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12861 ;; after the call to __morestack.
12862 (define_insn "split_stack_return"
12863   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12864   ""
12865   "blr"
12866   [(set_attr "type" "jmpreg")])
12868 ;; If there are operand 0 bytes available on the stack, jump to
12869 ;; operand 1.
12870 (define_expand "split_stack_space_check"
12871   [(set (match_dup 2)
12872         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12873    (set (match_dup 3)
12874         (minus (reg STACK_POINTER_REGNUM)
12875                (match_operand 0)))
12876    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12877    (set (pc) (if_then_else
12878               (geu (match_dup 4) (const_int 0))
12879               (label_ref (match_operand 1))
12880               (pc)))]
12881   ""
12883   rs6000_split_stack_space_check (operands[0], operands[1]);
12884   DONE;
12887 (define_insn "bpermd_<mode>"
12888   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12889         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12890                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12891   "TARGET_POPCNTD"
12892   "bpermd %0,%1,%2"
12893   [(set_attr "type" "popcnt")])
12896 ;; Builtin fma support.  Handle 
12897 ;; Note that the conditions for expansion are in the FMA_F iterator.
12899 (define_expand "fma<mode>4"
12900   [(set (match_operand:FMA_F 0 "register_operand" "")
12901         (fma:FMA_F
12902           (match_operand:FMA_F 1 "register_operand" "")
12903           (match_operand:FMA_F 2 "register_operand" "")
12904           (match_operand:FMA_F 3 "register_operand" "")))]
12905   ""
12906   "")
12908 (define_insn "*fma<mode>4_fpr"
12909   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12910         (fma:SFDF
12911           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12912           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12913           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12914   "TARGET_<MODE>_FPR"
12915   "@
12916    fmadd<Ftrad> %0,%1,%2,%3
12917    xsmadda<Fvsx> %x0,%x1,%x2
12918    xsmaddm<Fvsx> %x0,%x1,%x3"
12919   [(set_attr "type" "fp")
12920    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12922 ; Altivec only has fma and nfms.
12923 (define_expand "fms<mode>4"
12924   [(set (match_operand:FMA_F 0 "register_operand" "")
12925         (fma:FMA_F
12926           (match_operand:FMA_F 1 "register_operand" "")
12927           (match_operand:FMA_F 2 "register_operand" "")
12928           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12929   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12930   "")
12932 (define_insn "*fms<mode>4_fpr"
12933   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12934         (fma:SFDF
12935          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12936          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12937          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12938   "TARGET_<MODE>_FPR"
12939   "@
12940    fmsub<Ftrad> %0,%1,%2,%3
12941    xsmsuba<Fvsx> %x0,%x1,%x2
12942    xsmsubm<Fvsx> %x0,%x1,%x3"
12943   [(set_attr "type" "fp")
12944    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12946 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12947 (define_expand "fnma<mode>4"
12948   [(set (match_operand:FMA_F 0 "register_operand" "")
12949         (neg:FMA_F
12950           (fma:FMA_F
12951             (match_operand:FMA_F 1 "register_operand" "")
12952             (match_operand:FMA_F 2 "register_operand" "")
12953             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12954   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12955   "")
12957 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12958 (define_expand "fnms<mode>4"
12959   [(set (match_operand:FMA_F 0 "register_operand" "")
12960         (neg:FMA_F
12961           (fma:FMA_F
12962             (match_operand:FMA_F 1 "register_operand" "")
12963             (match_operand:FMA_F 2 "register_operand" "")
12964             (match_operand:FMA_F 3 "register_operand" ""))))]
12965   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12966   "")
12968 ; Not an official optab name, but used from builtins.
12969 (define_expand "nfma<mode>4"
12970   [(set (match_operand:FMA_F 0 "register_operand" "")
12971         (neg:FMA_F
12972           (fma:FMA_F
12973             (match_operand:FMA_F 1 "register_operand" "")
12974             (match_operand:FMA_F 2 "register_operand" "")
12975             (match_operand:FMA_F 3 "register_operand" ""))))]
12976   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12977   "")
12979 (define_insn "*nfma<mode>4_fpr"
12980   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12981         (neg:SFDF
12982          (fma:SFDF
12983           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12984           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12985           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12986   "TARGET_<MODE>_FPR"
12987   "@
12988    fnmadd<Ftrad> %0,%1,%2,%3
12989    xsnmadda<Fvsx> %x0,%x1,%x2
12990    xsnmaddm<Fvsx> %x0,%x1,%x3"
12991   [(set_attr "type" "fp")
12992    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12994 ; Not an official optab name, but used from builtins.
12995 (define_expand "nfms<mode>4"
12996   [(set (match_operand:FMA_F 0 "register_operand" "")
12997         (neg:FMA_F
12998           (fma:FMA_F
12999             (match_operand:FMA_F 1 "register_operand" "")
13000             (match_operand:FMA_F 2 "register_operand" "")
13001             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13002   ""
13003   "")
13005 (define_insn "*nfmssf4_fpr"
13006   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13007         (neg:SFDF
13008          (fma:SFDF
13009           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13010           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13011           (neg:SFDF
13012            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13013   "TARGET_<MODE>_FPR"
13014   "@
13015    fnmsub<Ftrad> %0,%1,%2,%3
13016    xsnmsuba<Fvsx> %x0,%x1,%x2
13017    xsnmsubm<Fvsx> %x0,%x1,%x3"
13018   [(set_attr "type" "fp")
13019    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13022 (define_expand "rs6000_get_timebase"
13023   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13024   ""
13026   if (TARGET_POWERPC64)
13027     emit_insn (gen_rs6000_mftb_di (operands[0]));
13028   else
13029     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13030   DONE;
13033 (define_insn "rs6000_get_timebase_ppc32"
13034   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13035         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13036    (clobber (match_scratch:SI 1 "=r"))
13037    (clobber (match_scratch:CC 2 "=y"))]
13038   "!TARGET_POWERPC64"
13040   if (WORDS_BIG_ENDIAN)
13041     if (TARGET_MFCRF)
13042       {
13043         return "mfspr %0,269\;"
13044                "mfspr %L0,268\;"
13045                "mfspr %1,269\;"
13046                "cmpw %2,%0,%1\;"
13047                "bne- %2,$-16";
13048       }
13049     else
13050       {
13051         return "mftbu %0\;"
13052                "mftb %L0\;"
13053                "mftbu %1\;"
13054                "cmpw %2,%0,%1\;"
13055                "bne- %2,$-16";
13056       }
13057   else
13058     if (TARGET_MFCRF)
13059       {
13060         return "mfspr %L0,269\;"
13061                "mfspr %0,268\;"
13062                "mfspr %1,269\;"
13063                "cmpw %2,%L0,%1\;"
13064                "bne- %2,$-16";
13065       }
13066     else
13067       {
13068         return "mftbu %L0\;"
13069                "mftb %0\;"
13070                "mftbu %1\;"
13071                "cmpw %2,%L0,%1\;"
13072                "bne- %2,$-16";
13073       }
13075   [(set_attr "length" "20")])
13077 (define_insn "rs6000_mftb_<mode>"
13078   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13079         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13080   ""
13082   if (TARGET_MFCRF)
13083     return "mfspr %0,268";
13084   else
13085     return "mftb %0";
13089 (define_insn "rs6000_mffs"
13090   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13091         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13092   "TARGET_HARD_FLOAT && TARGET_FPRS"
13093   "mffs %0")
13095 (define_insn "rs6000_mtfsf"
13096   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13097                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13098                     UNSPECV_MTFSF)]
13099   "TARGET_HARD_FLOAT && TARGET_FPRS"
13100   "mtfsf %0,%1")
13103 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13104 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13105 ;; register that is being loaded.  The fused ops must be physically adjacent.
13107 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13108 ;; before register allocation, and is meant to reduce the lifetime for the
13109 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13110 ;; to use the register that is being load.  The peephole2 then gathers any
13111 ;; other fused possibilities that it can find after register allocation.  If
13112 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13114 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13115 ;; before register allocation, so that we can avoid allocating a temporary base
13116 ;; register that won't be used, and that we try to load into base registers,
13117 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13118 ;; (addis followed by load) even on power8.
13120 (define_split
13121   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13122         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13123   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13124   [(parallel [(set (match_dup 0) (match_dup 2))
13125               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13126               (use (match_dup 3))
13127               (clobber (scratch:DI))])]
13129   operands[2] = fusion_wrap_memory_address (operands[1]);
13130   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13133 (define_insn "*toc_fusionload_<mode>"
13134   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13135         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13136    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13137    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13138    (clobber (match_scratch:DI 3 "=X,&b"))]
13139   "TARGET_TOC_FUSION_INT"
13141   if (base_reg_operand (operands[0], <MODE>mode))
13142     return emit_fusion_gpr_load (operands[0], operands[1]);
13144   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13146   [(set_attr "type" "load")
13147    (set_attr "length" "8")])
13149 (define_insn "*toc_fusionload_di"
13150   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13151         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13152    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13153    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13154    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13155   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13156    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13158   if (base_reg_operand (operands[0], DImode))
13159     return emit_fusion_gpr_load (operands[0], operands[1]);
13161   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13163   [(set_attr "type" "load")
13164    (set_attr "length" "8")])
13167 ;; Find cases where the addis that feeds into a load instruction is either used
13168 ;; once or is the same as the target register, and replace it with the fusion
13169 ;; insn
13171 (define_peephole2
13172   [(set (match_operand:P 0 "base_reg_operand" "")
13173         (match_operand:P 1 "fusion_gpr_addis" ""))
13174    (set (match_operand:INT1 2 "base_reg_operand" "")
13175         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13176   "TARGET_P8_FUSION
13177    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13178                          operands[3])"
13179   [(const_int 0)]
13181   expand_fusion_gpr_load (operands);
13182   DONE;
13185 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13186 ;; reload)
13188 (define_insn "fusion_gpr_load_<mode>"
13189   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13190         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13191                      UNSPEC_FUSION_GPR))]
13192   "TARGET_P8_FUSION"
13194   return emit_fusion_gpr_load (operands[0], operands[1]);
13196   [(set_attr "type" "load")
13197    (set_attr "length" "8")])
13200 ;; ISA 3.0 (power9) fusion support
13201 ;; Merge addis with floating load/store to FPRs (or GPRs).
13202 (define_peephole2
13203   [(set (match_operand:P 0 "base_reg_operand" "")
13204         (match_operand:P 1 "fusion_gpr_addis" ""))
13205    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13206         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13207   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13208    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13209   [(const_int 0)]
13211   expand_fusion_p9_load (operands);
13212   DONE;
13215 (define_peephole2
13216   [(set (match_operand:P 0 "base_reg_operand" "")
13217         (match_operand:P 1 "fusion_gpr_addis" ""))
13218    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13219         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13220   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13221    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13222   [(const_int 0)]
13224   expand_fusion_p9_store (operands);
13225   DONE;
13228 (define_peephole2
13229   [(set (match_operand:SDI 0 "int_reg_operand" "")
13230         (match_operand:SDI 1 "upper16_cint_operand" ""))
13231    (set (match_dup 0)
13232         (ior:SDI (match_dup 0)
13233                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13234   "TARGET_P9_FUSION"
13235   [(set (match_dup 0)
13236         (unspec:SDI [(match_dup 1)
13237                      (match_dup 2)] UNSPEC_FUSION_P9))])
13239 (define_peephole2
13240   [(set (match_operand:SDI 0 "int_reg_operand" "")
13241         (match_operand:SDI 1 "upper16_cint_operand" ""))
13242    (set (match_operand:SDI 2 "int_reg_operand" "")
13243         (ior:SDI (match_dup 0)
13244                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13245   "TARGET_P9_FUSION
13246    && !rtx_equal_p (operands[0], operands[2])
13247    && peep2_reg_dead_p (2, operands[0])"
13248   [(set (match_dup 2)
13249         (unspec:SDI [(match_dup 1)
13250                      (match_dup 3)] UNSPEC_FUSION_P9))])
13252 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13253 ;; reload).  Because we want to eventually have secondary_reload generate
13254 ;; these, they have to have a single alternative that gives the register
13255 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13256 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13257   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13258         (unspec:GPR_FUSION
13259          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13260          UNSPEC_FUSION_P9))
13261    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13262   "TARGET_P9_FUSION"
13264   /* This insn is a secondary reload insn, which cannot have alternatives.
13265      If we are not loading up register 0, use the power8 fusion instead.  */
13266   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13267     return emit_fusion_gpr_load (operands[0], operands[1]);
13269   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13271   [(set_attr "type" "load")
13272    (set_attr "length" "8")])
13274 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13275   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13276         (unspec:GPR_FUSION
13277          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13278          UNSPEC_FUSION_P9))
13279    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13280   "TARGET_P9_FUSION"
13282   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13284   [(set_attr "type" "store")
13285    (set_attr "length" "8")])
13287 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13288   [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13289         (unspec:FPR_FUSION
13290          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13291          UNSPEC_FUSION_P9))
13292    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13293   "TARGET_P9_FUSION"
13295   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13297   [(set_attr "type" "fpload")
13298    (set_attr "length" "8")])
13300 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13301   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13302         (unspec:FPR_FUSION
13303          [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13304          UNSPEC_FUSION_P9))
13305    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13306   "TARGET_P9_FUSION"
13308   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13310   [(set_attr "type" "fpstore")
13311    (set_attr "length" "8")])
13313 (define_insn "*fusion_p9_<mode>_constant"
13314   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13315         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13316                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13317                     UNSPEC_FUSION_P9))] 
13318   "TARGET_P9_FUSION"
13320   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13321   return "ori %0,%0,%2";
13323   [(set_attr "type" "two")
13324    (set_attr "length" "8")])
13327 ;; Miscellaneous ISA 2.06 (power7) instructions
13328 (define_insn "addg6s"
13329   [(set (match_operand:SI 0 "register_operand" "=r")
13330         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13331                     (match_operand:SI 2 "register_operand" "r")]
13332                    UNSPEC_ADDG6S))]
13333   "TARGET_POPCNTD"
13334   "addg6s %0,%1,%2"
13335   [(set_attr "type" "integer")
13336    (set_attr "length" "4")])
13338 (define_insn "cdtbcd"
13339   [(set (match_operand:SI 0 "register_operand" "=r")
13340         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13341                    UNSPEC_CDTBCD))]
13342   "TARGET_POPCNTD"
13343   "cdtbcd %0,%1"
13344   [(set_attr "type" "integer")
13345    (set_attr "length" "4")])
13347 (define_insn "cbcdtd"
13348   [(set (match_operand:SI 0 "register_operand" "=r")
13349         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13350                    UNSPEC_CBCDTD))]
13351   "TARGET_POPCNTD"
13352   "cbcdtd %0,%1"
13353   [(set_attr "type" "integer")
13354    (set_attr "length" "4")])
13356 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13357                                         UNSPEC_DIVEO
13358                                         UNSPEC_DIVEU
13359                                         UNSPEC_DIVEUO])
13361 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13362                              (UNSPEC_DIVEO      "eo")
13363                              (UNSPEC_DIVEU      "eu")
13364                              (UNSPEC_DIVEUO     "euo")])
13366 (define_insn "div<div_extend>_<mode>"
13367   [(set (match_operand:GPR 0 "register_operand" "=r")
13368         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13369                      (match_operand:GPR 2 "register_operand" "r")]
13370                     UNSPEC_DIV_EXTEND))]
13371   "TARGET_POPCNTD"
13372   "div<wd><div_extend> %0,%1,%2"
13373   [(set_attr "type" "div")
13374    (set_attr "size" "<bits>")])
13377 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13379 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13380 (define_mode_attr FP128_64 [(TF "DF")
13381                             (IF "DF")
13382                             (TD "DI")
13383                             (KF "DI")])
13385 (define_expand "unpack<mode>"
13386   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13387         (unspec:<FP128_64>
13388          [(match_operand:FMOVE128 1 "register_operand" "")
13389           (match_operand:QI 2 "const_0_to_1_operand" "")]
13390          UNSPEC_UNPACK_128BIT))]
13391   "FLOAT128_2REG_P (<MODE>mode)"
13392   "")
13394 (define_insn_and_split "unpack<mode>_dm"
13395   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13396         (unspec:<FP128_64>
13397          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13398           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13399          UNSPEC_UNPACK_128BIT))]
13400   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13401   "#"
13402   "&& reload_completed"
13403   [(set (match_dup 0) (match_dup 3))]
13405   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13407   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13408     {
13409       emit_note (NOTE_INSN_DELETED);
13410       DONE;
13411     }
13413   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13415   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13416    (set_attr "length" "4")])
13418 (define_insn_and_split "unpack<mode>_nodm"
13419   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13420         (unspec:<FP128_64>
13421          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13422           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13423          UNSPEC_UNPACK_128BIT))]
13424   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13425   "#"
13426   "&& reload_completed"
13427   [(set (match_dup 0) (match_dup 3))]
13429   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13431   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13432     {
13433       emit_note (NOTE_INSN_DELETED);
13434       DONE;
13435     }
13437   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13439   [(set_attr "type" "fp,fpstore")
13440    (set_attr "length" "4")])
13442 (define_insn_and_split "pack<mode>"
13443   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13444         (unspec:FMOVE128
13445          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13446           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13447          UNSPEC_PACK_128BIT))]
13448   "FLOAT128_2REG_P (<MODE>mode)"
13449   "@
13450    fmr %L0,%2
13451    #"
13452   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13453   [(set (match_dup 3) (match_dup 1))
13454    (set (match_dup 4) (match_dup 2))]
13456   unsigned dest_hi = REGNO (operands[0]);
13457   unsigned dest_lo = dest_hi + 1;
13459   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13460   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13462   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13463   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13465   [(set_attr "type" "fpsimple,fp")
13466    (set_attr "length" "4,8")])
13468 (define_insn "unpack<mode>"
13469   [(set (match_operand:DI 0 "register_operand" "=d,d")
13470         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13471                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13472          UNSPEC_UNPACK_128BIT))]
13473   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13475   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13476     return ASM_COMMENT_START " xxpermdi to same register";
13478   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13479   return "xxpermdi %x0,%x1,%x1,%3";
13481   [(set_attr "type" "vecperm")])
13483 (define_insn "pack<mode>"
13484   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13485         (unspec:FMOVE128_VSX
13486          [(match_operand:DI 1 "register_operand" "d")
13487           (match_operand:DI 2 "register_operand" "d")]
13488          UNSPEC_PACK_128BIT))]
13489   "TARGET_VSX"
13490   "xxpermdi %x0,%x1,%x2,0"
13491   [(set_attr "type" "vecperm")])
13495 ;; ISA 2.08 IEEE 128-bit floating point support.
13497 (define_insn "add<mode>3"
13498   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13499         (plus:IEEE128
13500          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13501          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13502   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13503   "xsaddqp %0,%1,%2"
13504   [(set_attr "type" "vecfloat")
13505    (set_attr "size" "128")])
13507 (define_insn "sub<mode>3"
13508   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13509         (minus:IEEE128
13510          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13511          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13512   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13513   "xssubqp %0,%1,%2"
13514   [(set_attr "type" "vecfloat")
13515    (set_attr "size" "128")])
13517 (define_insn "mul<mode>3"
13518   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13519         (mult:IEEE128
13520          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13521          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13522   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13523   "xsmulqp %0,%1,%2"
13524   [(set_attr "type" "vecfloat")
13525    (set_attr "size" "128")])
13527 (define_insn "div<mode>3"
13528   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13529         (div:IEEE128
13530          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13531          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13532   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13533   "xsdivqp %0,%1,%2"
13534   [(set_attr "type" "vecdiv")
13535    (set_attr "size" "128")])
13537 (define_insn "sqrt<mode>2"
13538   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13539         (sqrt:IEEE128
13540          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13541   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13542    "xssqrtqp %0,%1"
13543   [(set_attr "type" "vecdiv")
13544    (set_attr "size" "128")])
13546 (define_expand "copysign<mode>3"
13547   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13548    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13549    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13550   "FLOAT128_IEEE_P (<MODE>mode)"
13552   if (TARGET_FLOAT128_HW)
13553     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13554                                          operands[2]));
13555   else
13556     {
13557       rtx tmp = gen_reg_rtx (<MODE>mode);
13558       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13559                                            operands[2], tmp));
13560     }
13561   DONE;
13564 (define_insn "copysign<mode>3_hard"
13565   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13566         (unspec:IEEE128
13567          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13568           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13569          UNSPEC_COPYSIGN))]
13570   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13571    "xscpsgnqp %0,%2,%1"
13572   [(set_attr "type" "vecmove")
13573    (set_attr "size" "128")])
13575 (define_insn "copysign<mode>3_soft"
13576   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13577         (unspec:IEEE128
13578          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13579           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13580           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13581          UNSPEC_COPYSIGN))]
13582   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13583    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13584   [(set_attr "type" "veccomplex")
13585    (set_attr "length" "8")])
13587 (define_insn "neg<mode>2_hw"
13588   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13589         (neg:IEEE128
13590          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13591   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13592   "xsnegqp %0,%1"
13593   [(set_attr "type" "vecmove")
13594    (set_attr "size" "128")])
13597 (define_insn "abs<mode>2_hw"
13598   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13599         (abs:IEEE128
13600          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13601   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13602   "xsabsqp %0,%1"
13603   [(set_attr "type" "vecmove")
13604    (set_attr "size" "128")])
13607 (define_insn "*nabs<mode>2_hw"
13608   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13609         (neg:IEEE128
13610          (abs:IEEE128
13611           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13612   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13613   "xsnabsqp %0,%1"
13614   [(set_attr "type" "vecmove")
13615    (set_attr "size" "128")])
13617 ;; Initially don't worry about doing fusion
13618 (define_insn "*fma<mode>4_hw"
13619   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13620         (fma:IEEE128
13621          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13622          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13623          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13624   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13625   "xsmaddqp %0,%1,%2"
13626   [(set_attr "type" "vecfloat")
13627    (set_attr "size" "128")])
13629 (define_insn "*fms<mode>4_hw"
13630   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13631         (fma:IEEE128
13632          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13633          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13634          (neg:IEEE128
13635           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13636   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13637   "xsmsubqp %0,%1,%2"
13638   [(set_attr "type" "vecfloat")
13639    (set_attr "size" "128")])
13641 (define_insn "*nfma<mode>4_hw"
13642   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13643         (neg:IEEE128
13644          (fma:IEEE128
13645           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13646           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13647           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13648   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13649   "xsnmaddqp %0,%1,%2"
13650   [(set_attr "type" "vecfloat")
13651    (set_attr "size" "128")])
13653 (define_insn "*nfms<mode>4_hw"
13654   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13655         (neg:IEEE128
13656          (fma:IEEE128
13657           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13658           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13659           (neg:IEEE128
13660            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13661   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13662   "xsnmsubqp %0,%1,%2"
13663   [(set_attr "type" "vecfloat")
13664    (set_attr "size" "128")])
13666 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13667   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13668         (float_extend:IEEE128
13669          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13670   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13671   "xscvdpqp %0,%1"
13672   [(set_attr "type" "vecfloat")
13673    (set_attr "size" "128")])
13675 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13676 ;; point is a simple copy.
13677 (define_insn_and_split "extendkftf2"
13678   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13679         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13680   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13681   "@
13682    #
13683    xxlor %x0,%x1,%x1"
13684   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13685   [(const_int 0)]
13687   emit_note (NOTE_INSN_DELETED);
13688   DONE;
13690   [(set_attr "type" "*,veclogical")
13691    (set_attr "length" "0,4")])
13693 (define_insn_and_split "trunctfkf2"
13694   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13695         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13696   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13697   "@
13698    #
13699    xxlor %x0,%x1,%x1"
13700   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13701   [(const_int 0)]
13703   emit_note (NOTE_INSN_DELETED);
13704   DONE;
13706   [(set_attr "type" "*,veclogical")
13707    (set_attr "length" "0,4")])
13709 (define_insn "trunc<mode>df2_hw"
13710   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13711         (float_truncate:DF
13712          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13713   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13714   "xscvqpdp %0,%1"
13715   [(set_attr "type" "vecfloat")
13716    (set_attr "size" "128")])
13718 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13719 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13720 ;; conversion
13721 (define_insn_and_split "trunc<mode>sf2_hw"
13722   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13723         (float_truncate:SF
13724          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13725    (clobber (match_scratch:DF 2 "=v"))]
13726   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13727   "#"
13728   "&& 1"
13729   [(set (match_dup 2)
13730         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13731    (set (match_dup 0)
13732         (float_truncate:SF (match_dup 2)))]
13734   if (GET_CODE (operands[2]) == SCRATCH)
13735     operands[2] = gen_reg_rtx (DFmode);
13737   [(set_attr "type" "vecfloat")
13738    (set_attr "length" "8")])
13740 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13741 ;; allowed in the traditional floating point registers. Use V2DImode so that
13742 ;; we can get a value in an Altivec register.
13744 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13745   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13746         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13747    (clobber (match_scratch:V2DI 2 "=v,v"))]
13748   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13749   "#"
13750   "&& 1"
13751   [(pc)]
13753   convert_float128_to_int (operands, <CODE>);
13754   DONE;
13756   [(set_attr "length" "8")
13757    (set_attr "type" "mftgpr,fpstore")])
13759 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13760   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13761         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13762    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13763   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13764   "#"
13765   "&& 1"
13766   [(pc)]
13768   convert_float128_to_int (operands, <CODE>);
13769   DONE;
13771   [(set_attr "length" "8")
13772    (set_attr "type" "mftgpr,vecsimple,fpstore")])
13774 (define_insn_and_split "float<uns>_<mode>si2_hw"
13775   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13776         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13777    (clobber (match_scratch:V2DI 2 "=v,v"))]
13778   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13779   "#"
13780   "&& 1"
13781   [(pc)]
13783   convert_int_to_float128 (operands, <CODE>);
13784   DONE;
13786   [(set_attr "length" "8")
13787    (set_attr "type" "vecfloat")])
13789 (define_insn_and_split "float<uns>_<mode>di2_hw"
13790   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13791         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13792    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13793   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13794   "#"
13795   "&& 1"
13796   [(pc)]
13798   convert_int_to_float128 (operands, <CODE>);
13799   DONE;
13801   [(set_attr "length" "8")
13802    (set_attr "type" "vecfloat")])
13804 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13805 (define_insn "*xscvqp<su>wz_<mode>"
13806   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13807         (unspec:V2DI
13808          [(any_fix:SI
13809            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13810          UNSPEC_IEEE128_CONVERT))]
13811   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13812   "xscvqp<su>wz %0,%1"
13813   [(set_attr "type" "vecfloat")
13814    (set_attr "size" "128")])
13816 (define_insn "*xscvqp<su>dz_<mode>"
13817   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13818         (unspec:V2DI
13819          [(any_fix:DI
13820            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13821          UNSPEC_IEEE128_CONVERT))]
13822   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13823   "xscvqp<su>dz %0,%1"
13824   [(set_attr "type" "vecfloat")
13825    (set_attr "size" "128")])
13827 (define_insn "*xscv<su>dqp_<mode>"
13828   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13829         (any_float:IEEE128
13830          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13831                     UNSPEC_IEEE128_CONVERT)))]
13832   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13833   "xscv<su>dqp %0,%1"
13834   [(set_attr "type" "vecfloat")
13835    (set_attr "size" "128")])
13837 (define_insn "*ieee128_mfvsrd_64bit"
13838   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13839         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13840                    UNSPEC_IEEE128_MOVE))]
13841   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13842   "@
13843    mfvsrd %0,%x1
13844    stxsdx %x1,%y0
13845    xxlor %x0,%x1,%x1"
13846   [(set_attr "type" "mftgpr,fpstore,veclogical")])
13849 (define_insn "*ieee128_mfvsrd_32bit"
13850   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13851         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13852                    UNSPEC_IEEE128_MOVE))]
13853   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13854   "@
13855    stxsdx %x1,%y0
13856    xxlor %x0,%x1,%x1"
13857   [(set_attr "type" "fpstore,veclogical")])
13859 (define_insn "*ieee128_mfvsrwz"
13860   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13861         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13862                    UNSPEC_IEEE128_MOVE))]
13863   "TARGET_FLOAT128_HW"
13864   "@
13865    mfvsrwz %0,%x1
13866    stxsiwx %x1,%y0"
13867   [(set_attr "type" "mftgpr,fpstore")])
13869 ;; 0 says do sign-extension, 1 says zero-extension
13870 (define_insn "*ieee128_mtvsrw"
13871   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13872         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13873                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13874                      UNSPEC_IEEE128_MOVE))]
13875   "TARGET_FLOAT128_HW"
13876   "@
13877    mtvsrwa %x0,%1
13878    lxsiwax %x0,%y1
13879    mtvsrwz %x0,%1
13880    lxsiwzx %x0,%y1"
13881   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13884 (define_insn "*ieee128_mtvsrd_64bit"
13885   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13886         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13887                      UNSPEC_IEEE128_MOVE))]
13888   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13889   "@
13890    mtvsrd %x0,%1
13891    lxsdx %x0,%y1
13892    xxlor %x0,%x1,%x1"
13893   [(set_attr "type" "mffgpr,fpload,veclogical")])
13895 (define_insn "*ieee128_mtvsrd_32bit"
13896   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13897         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13898                      UNSPEC_IEEE128_MOVE))]
13899   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13900   "@
13901    lxsdx %x0,%y1
13902    xxlor %x0,%x1,%x1"
13903   [(set_attr "type" "fpload,veclogical")])
13905 ;; IEEE 128-bit instructions with round to odd semantics
13906 (define_insn "*trunc<mode>df2_odd"
13907   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13908         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13909                    UNSPEC_ROUND_TO_ODD))]
13910   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13911   "xscvqpdpo %0,%1"
13912   [(set_attr "type" "vecfloat")
13913    (set_attr "size" "128")])
13915 ;; IEEE 128-bit comparisons
13916 (define_insn "*cmp<mode>_hw"
13917   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13918         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13919                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13920   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13921    "xscmpuqp %0,%1,%2"
13922   [(set_attr "type" "veccmp")
13923    (set_attr "size" "128")])
13927 (include "sync.md")
13928 (include "vector.md")
13929 (include "vsx.md")
13930 (include "altivec.md")
13931 (include "spe.md")
13932 (include "dfp.md")
13933 (include "paired.md")
13934 (include "crypto.md")
13935 (include "htm.md")