PR target/69810
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob5566185076a16cdc748f4cbd798a6b5fda01b4a4
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   ])
153 ;; UNSPEC_VOLATILE usage
156 (define_c_enum "unspecv"
157   [UNSPECV_BLOCK
158    UNSPECV_LL                   ; load-locked
159    UNSPECV_SC                   ; store-conditional
160    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
161    UNSPECV_EH_RR                ; eh_reg_restore
162    UNSPECV_ISYNC                ; isync instruction
163    UNSPECV_MFTB                 ; move from time base
164    UNSPECV_NLGR                 ; non-local goto receiver
165    UNSPECV_MFFS                 ; Move from FPSCR
166    UNSPECV_MTFSF                ; Move to FPSCR Fields
167    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
168   ])
171 ;; Define an insn type attribute.  This is used in function unit delay
172 ;; computations.
173 (define_attr "type"
174   "integer,two,three,
175    add,logical,shift,insert,
176    mul,halfmul,div,
177    exts,cntlz,popcnt,isel,
178    load,store,fpload,fpstore,vecload,vecstore,
179    cmp,
180    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
181    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
182    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
183    brinc,
184    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
185    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
186    htm"
187   (const_string "integer"))
189 ;; What data size does this instruction work on?
190 ;; This is used for insert, mul.
191 (define_attr "size" "8,16,32,64" (const_string "32"))
193 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
194 ;; This is used for add, logical, shift, exts, mul.
195 (define_attr "dot" "no,yes" (const_string "no"))
197 ;; Does this instruction sign-extend its result?
198 ;; This is used for load insns.
199 (define_attr "sign_extend" "no,yes" (const_string "no"))
201 ;; Does this instruction use indexed (that is, reg+reg) addressing?
202 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
203 ;; it is automatically set based on that.  If a load or store instruction
204 ;; has fewer than two operands it needs to set this attribute manually
205 ;; or the compiler will crash.
206 (define_attr "indexed" "no,yes"
207   (if_then_else (ior (match_operand 0 "indexed_address_mem")
208                      (match_operand 1 "indexed_address_mem"))
209                 (const_string "yes")
210                 (const_string "no")))
212 ;; Does this instruction use update addressing?
213 ;; This is used for load and store insns.  See the comments for "indexed".
214 (define_attr "update" "no,yes"
215   (if_then_else (ior (match_operand 0 "update_address_mem")
216                      (match_operand 1 "update_address_mem"))
217                 (const_string "yes")
218                 (const_string "no")))
220 ;; Is this instruction using operands[2] as shift amount, and can that be a
221 ;; register?
222 ;; This is used for shift insns.
223 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
225 ;; Is this instruction using a shift amount from a register?
226 ;; This is used for shift insns.
227 (define_attr "var_shift" "no,yes"
228   (if_then_else (and (eq_attr "type" "shift")
229                      (eq_attr "maybe_var_shift" "yes"))
230                 (if_then_else (match_operand 2 "gpc_reg_operand")
231                               (const_string "yes")
232                               (const_string "no"))
233                 (const_string "no")))
235 ;; Is copying of this instruction disallowed?
236 (define_attr "cannot_copy" "no,yes" (const_string "no"))
238 ;; Define floating point instruction sub-types for use with Xfpu.md
239 (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"))
241 ;; Length (in bytes).
242 ; '(pc)' in the following doesn't include the instruction itself; it is
243 ; calculated as if the instruction had zero size.
244 (define_attr "length" ""
245   (if_then_else (eq_attr "type" "branch")
246                 (if_then_else (and (ge (minus (match_dup 0) (pc))
247                                        (const_int -32768))
248                                    (lt (minus (match_dup 0) (pc))
249                                        (const_int 32764)))
250                               (const_int 4)
251                               (const_int 8))
252                 (const_int 4)))
254 ;; Processor type -- this attribute must exactly match the processor_type
255 ;; enumeration in rs6000-opts.h.
256 (define_attr "cpu"
257   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
258    ppc750,ppc7400,ppc7450,
259    ppc403,ppc405,ppc440,ppc476,
260    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
261    power4,power5,power6,power7,power8,power9,
262    rs64a,mpccore,cell,ppca2,titan"
263   (const (symbol_ref "rs6000_cpu_attr")))
266 ;; If this instruction is microcoded on the CELL processor
267 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
268 (define_attr "cell_micro" "not,conditional,always"
269   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
270                           (eq_attr "dot" "yes"))
271                      (and (eq_attr "type" "load")
272                           (eq_attr "sign_extend" "yes"))
273                      (and (eq_attr "type" "shift")
274                           (eq_attr "var_shift" "yes")))
275                 (const_string "always")
276                 (const_string "not")))
278 (automata_option "ndfa")
280 (include "rs64.md")
281 (include "mpc.md")
282 (include "40x.md")
283 (include "440.md")
284 (include "476.md")
285 (include "601.md")
286 (include "603.md")
287 (include "6xx.md")
288 (include "7xx.md")
289 (include "7450.md")
290 (include "8540.md")
291 (include "e300c2c3.md")
292 (include "e500mc.md")
293 (include "e500mc64.md")
294 (include "e5500.md")
295 (include "e6500.md")
296 (include "power4.md")
297 (include "power5.md")
298 (include "power6.md")
299 (include "power7.md")
300 (include "power8.md")
301 (include "cell.md")
302 (include "xfpu.md")
303 (include "a2.md")
304 (include "titan.md")
306 (include "predicates.md")
307 (include "constraints.md")
309 (include "darwin.md")
312 ;; Mode iterators
314 ; This mode iterator allows :GPR to be used to indicate the allowable size
315 ; of whole values in GPRs.
316 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
318 ; Any supported integer mode.
319 (define_mode_iterator INT [QI HI SI DI TI PTI])
321 ; Any supported integer mode that fits in one register.
322 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
324 ; Everything we can extend QImode to.
325 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
327 ; Everything we can extend HImode to.
328 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
330 ; Everything we can extend SImode to.
331 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
333 ; QImode or HImode for small atomic ops
334 (define_mode_iterator QHI [QI HI])
336 ; QImode, HImode, SImode for fused ops only for GPR loads
337 (define_mode_iterator QHSI [QI HI SI])
339 ; HImode or SImode for sign extended fusion ops
340 (define_mode_iterator HSI [HI SI])
342 ; SImode or DImode, even if DImode doesn't fit in GPRs.
343 (define_mode_iterator SDI [SI DI])
345 ; Types that can be fused with an ADDIS instruction to load or store a GPR
346 ; register that has reg+offset addressing.
347 (define_mode_iterator GPR_FUSION [QI
348                                   HI
349                                   SI
350                                   (DI   "TARGET_POWERPC64")
351                                   SF
352                                   (DF   "TARGET_POWERPC64")])
354 ; Types that can be fused with an ADDIS instruction to load or store a FPR
355 ; register that has reg+offset addressing.
356 (define_mode_iterator FPR_FUSION [DI SF DF])
358 ; The size of a pointer.  Also, the size of the value that a record-condition
359 ; (one with a '.') will compare; and the size used for arithmetic carries.
360 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
362 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
363 ; PTImode is GPR only)
364 (define_mode_iterator TI2 [TI PTI])
366 ; Any hardware-supported floating-point mode
367 (define_mode_iterator FP [
368   (SF "TARGET_HARD_FLOAT 
369    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
370   (DF "TARGET_HARD_FLOAT 
371    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
372   (TF "TARGET_HARD_FLOAT
373    && (TARGET_FPRS || TARGET_E500_DOUBLE)
374    && TARGET_LONG_DOUBLE_128")
375   (IF "TARGET_FLOAT128")
376   (KF "TARGET_FLOAT128")
377   (DD "TARGET_DFP")
378   (TD "TARGET_DFP")])
380 ; Any fma capable floating-point mode.
381 (define_mode_iterator FMA_F [
382   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
383   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
384        || VECTOR_UNIT_VSX_P (DFmode)")
385   (V2SF "TARGET_PAIRED_FLOAT")
386   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
387   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
388   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
389   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
390   ])
392 ; Floating point move iterators to combine binary and decimal moves
393 (define_mode_iterator FMOVE32 [SF SD])
394 (define_mode_iterator FMOVE64 [DF DD])
395 (define_mode_iterator FMOVE64X [DI DF DD])
396 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
397                                 (IF "TARGET_LONG_DOUBLE_128")
398                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
400 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
401                                     (IF "FLOAT128_2REG_P (IFmode)")
402                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
404 ; Iterators for 128 bit types for direct move
405 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
406                                     (V16QI "")
407                                     (V8HI  "")
408                                     (V4SI  "")
409                                     (V4SF  "")
410                                     (V2DI  "")
411                                     (V2DF  "")
412                                     (V1TI  "")
413                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
414                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
416 ; Iterator for 128-bit VSX types for pack/unpack
417 (define_mode_iterator FMOVE128_VSX [V1TI KF])
419 ; Whether a floating point move is ok, don't allow SD without hardware FP
420 (define_mode_attr fmove_ok [(SF "")
421                             (DF "")
422                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
423                             (DD "")])
425 ; Convert REAL_VALUE to the appropriate bits
426 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
427                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
428                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
429                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
431 ; Whether 0.0 has an all-zero bit pattern
432 (define_mode_attr zero_fp [(SF "j")
433                            (DF "j")
434                            (TF "j")
435                            (IF "j")
436                            (KF "j")
437                            (SD "wn")
438                            (DD "wn")
439                            (TD "wn")])
441 ; Definitions for load to 32-bit fpr register
442 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
443 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
444 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
445 (define_mode_attr f32_lm2 [(SF "o")               (SD "wn")])
446 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
447 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
448 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
450 ; Definitions for store from 32-bit fpr register
451 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
452 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
453 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
454 (define_mode_attr f32_sm2 [(SF "o")                (SD "wn")])
455 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
456 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
457 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwzx %x1,%y0")])
459 ; Definitions for 32-bit fpr direct move
460 ; At present, the decimal modes are not allowed in the traditional altivec
461 ; registers, so restrict the constraints to just the traditional FPRs.
462 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
464 ; Definitions for 32-bit VSX
465 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
467 ; Definitions for 32-bit use of altivec registers
468 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
470 ; Definitions for 64-bit VSX
471 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
473 ; Definitions for 64-bit direct move
474 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
476 ; Definitions for 64-bit use of altivec registers
477 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
479 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
480 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
482 ; These modes do not fit in integer registers in 32-bit mode.
483 ; but on e500v2, the gpr are 64 bit registers
484 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
486 ; Iterator for reciprocal estimate instructions
487 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
489 ; Iterator for just SF/DF
490 (define_mode_iterator SFDF [SF DF])
492 ; Iterator for 128-bit floating point that uses the IBM double-double format
493 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
494                               (TF "FLOAT128_IBM_P (TFmode)")])
496 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
497 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
498                                (TF "FLOAT128_IEEE_P (TFmode)")])
500 ; Iterator for 128-bit floating point
501 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
502                                 (IF "TARGET_FLOAT128")
503                                 (TF "TARGET_LONG_DOUBLE_128")])
505 ; SF/DF suffix for traditional floating instructions
506 (define_mode_attr Ftrad         [(SF "s") (DF "")])
508 ; SF/DF suffix for VSX instructions
509 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
511 ; SF/DF constraint for arithmetic on traditional floating point registers
512 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
514 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
515 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
516 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
517 ; format.
518 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
520 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
521 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
522 ; instructions added in ISA 2.07 (power8)
523 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
525 ; SF/DF constraint for arithmetic on altivec registers
526 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
528 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
529 (define_mode_attr Fs            [(SF "s")  (DF "d")])
531 ; FRE/FRES support
532 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
533 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
535 ; Conditional returns.
536 (define_code_iterator any_return [return simple_return])
537 (define_code_attr return_pred [(return "direct_return ()")
538                                (simple_return "1")])
539 (define_code_attr return_str [(return "") (simple_return "simple_")])
541 ; Logical operators.
542 (define_code_iterator iorxor [ior xor])
544 ; Signed/unsigned variants of ops.
545 (define_code_iterator any_extend        [sign_extend zero_extend])
546 (define_code_iterator any_fix           [fix unsigned_fix])
547 (define_code_iterator any_float         [float unsigned_float])
549 (define_code_attr u  [(sign_extend      "")
550                       (zero_extend      "u")])
552 (define_code_attr su [(sign_extend      "s")
553                       (zero_extend      "u")
554                       (fix              "s")
555                       (unsigned_fix     "s")
556                       (float            "s")
557                       (unsigned_float   "u")])
559 (define_code_attr az [(sign_extend      "a")
560                       (zero_extend      "z")
561                       (fix              "a")
562                       (unsigned_fix     "z")
563                       (float            "a")
564                       (unsigned_float   "z")])
566 (define_code_attr uns [(fix             "")
567                        (unsigned_fix    "uns")
568                        (float           "")
569                        (unsigned_float  "uns")])
571 ; Various instructions that come in SI and DI forms.
572 ; A generic w/d attribute, for things like cmpw/cmpd.
573 (define_mode_attr wd [(QI    "b")
574                       (HI    "h")
575                       (SI    "w")
576                       (DI    "d")
577                       (V16QI "b")
578                       (V8HI  "h")
579                       (V4SI  "w")
580                       (V2DI  "d")])
582 ;; How many bits in this mode?
583 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
585 ; DImode bits
586 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
588 ;; ISEL/ISEL64 target selection
589 (define_mode_attr sel [(SI "") (DI "64")])
591 ;; Bitmask for shift instructions
592 (define_mode_attr hH [(SI "h") (DI "H")])
594 ;; A mode twice the size of the given mode
595 (define_mode_attr dmode [(SI "di") (DI "ti")])
596 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
598 ;; Suffix for reload patterns
599 (define_mode_attr ptrsize [(SI "32bit")
600                            (DI "64bit")])
602 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
603                             (DI "TARGET_64BIT")])
605 (define_mode_attr mptrsize [(SI "si")
606                             (DI "di")])
608 (define_mode_attr ptrload [(SI "lwz")
609                            (DI "ld")])
611 (define_mode_attr ptrm [(SI "m")
612                         (DI "Y")])
614 (define_mode_attr rreg [(SF   "f")
615                         (DF   "ws")
616                         (TF   "f")
617                         (TD   "f")
618                         (V4SF "wf")
619                         (V2DF "wd")])
621 (define_mode_attr rreg2 [(SF   "f")
622                          (DF   "d")])
624 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
625                                  (DF "TARGET_FCFID")])
627 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
628                                 (DF "TARGET_E500_DOUBLE")])
630 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
631                                 (DF "TARGET_DOUBLE_FLOAT")])
633 ;; Mode iterator for logical operations on 128-bit types
634 (define_mode_iterator BOOL_128          [TI
635                                          PTI
636                                          (V16QI "TARGET_ALTIVEC")
637                                          (V8HI  "TARGET_ALTIVEC")
638                                          (V4SI  "TARGET_ALTIVEC")
639                                          (V4SF  "TARGET_ALTIVEC")
640                                          (V2DI  "TARGET_ALTIVEC")
641                                          (V2DF  "TARGET_ALTIVEC")
642                                          (V1TI  "TARGET_ALTIVEC")])
644 ;; For the GPRs we use 3 constraints for register outputs, two that are the
645 ;; same as the output register, and a third where the output register is an
646 ;; early clobber, so we don't have to deal with register overlaps.  For the
647 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
648 ;; either.
650 ;; Mode attribute for boolean operation register constraints for output
651 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
652                                          (PTI   "&r,r,r")
653                                          (V16QI "wa,v,&?r,?r,?r")
654                                          (V8HI  "wa,v,&?r,?r,?r")
655                                          (V4SI  "wa,v,&?r,?r,?r")
656                                          (V4SF  "wa,v,&?r,?r,?r")
657                                          (V2DI  "wa,v,&?r,?r,?r")
658                                          (V2DF  "wa,v,&?r,?r,?r")
659                                          (V1TI  "wa,v,&?r,?r,?r")])
661 ;; Mode attribute for boolean operation register constraints for operand1
662 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
663                                          (PTI   "r,0,r")
664                                          (V16QI "wa,v,r,0,r")
665                                          (V8HI  "wa,v,r,0,r")
666                                          (V4SI  "wa,v,r,0,r")
667                                          (V4SF  "wa,v,r,0,r")
668                                          (V2DI  "wa,v,r,0,r")
669                                          (V2DF  "wa,v,r,0,r")
670                                          (V1TI  "wa,v,r,0,r")])
672 ;; Mode attribute for boolean operation register constraints for operand2
673 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
674                                          (PTI   "r,r,0")
675                                          (V16QI "wa,v,r,r,0")
676                                          (V8HI  "wa,v,r,r,0")
677                                          (V4SI  "wa,v,r,r,0")
678                                          (V4SF  "wa,v,r,r,0")
679                                          (V2DI  "wa,v,r,r,0")
680                                          (V2DF  "wa,v,r,r,0")
681                                          (V1TI  "wa,v,r,r,0")])
683 ;; Mode attribute for boolean operation register constraints for operand1
684 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
685 ;; is used for operand1 or operand2
686 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
687                                          (PTI   "r,0,0")
688                                          (V16QI "wa,v,r,0,0")
689                                          (V8HI  "wa,v,r,0,0")
690                                          (V4SI  "wa,v,r,0,0")
691                                          (V4SF  "wa,v,r,0,0")
692                                          (V2DI  "wa,v,r,0,0")
693                                          (V2DF  "wa,v,r,0,0")
694                                          (V1TI  "wa,v,r,0,0")])
696 ;; Reload iterator for creating the function to allocate a base register to
697 ;; supplement addressing modes.
698 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
699                               SF SD SI DF DD DI TI PTI KF IF TF])
702 ;; Start with fixed-point load and store insns.  Here we put only the more
703 ;; complex forms.  Basic data transfer is done later.
705 (define_insn "zero_extendqi<mode>2"
706   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
707         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
708   ""
709   "@
710    lbz%U1%X1 %0,%1
711    rlwinm %0,%1,0,0xff"
712   [(set_attr "type" "load,shift")])
714 (define_insn_and_split "*zero_extendqi<mode>2_dot"
715   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
716         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
717                     (const_int 0)))
718    (clobber (match_scratch:EXTQI 0 "=r,r"))]
719   "rs6000_gen_cell_microcode"
720   "@
721    andi. %0,%1,0xff
722    #"
723   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
724   [(set (match_dup 0)
725         (zero_extend:EXTQI (match_dup 1)))
726    (set (match_dup 2)
727         (compare:CC (match_dup 0)
728                     (const_int 0)))]
729   ""
730   [(set_attr "type" "logical")
731    (set_attr "dot" "yes")
732    (set_attr "length" "4,8")])
734 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
735   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
736         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
737                     (const_int 0)))
738    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
739         (zero_extend:EXTQI (match_dup 1)))]
740   "rs6000_gen_cell_microcode"
741   "@
742    andi. %0,%1,0xff
743    #"
744   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
745   [(set (match_dup 0)
746         (zero_extend:EXTQI (match_dup 1)))
747    (set (match_dup 2)
748         (compare:CC (match_dup 0)
749                     (const_int 0)))]
750   ""
751   [(set_attr "type" "logical")
752    (set_attr "dot" "yes")
753    (set_attr "length" "4,8")])
756 (define_insn "zero_extendhi<mode>2"
757   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
758         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
759   ""
760   "@
761    lhz%U1%X1 %0,%1
762    rlwinm %0,%1,0,0xffff"
763   [(set_attr "type" "load,shift")])
765 (define_insn_and_split "*zero_extendhi<mode>2_dot"
766   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
767         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
768                     (const_int 0)))
769    (clobber (match_scratch:EXTHI 0 "=r,r"))]
770   "rs6000_gen_cell_microcode"
771   "@
772    andi. %0,%1,0xffff
773    #"
774   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
775   [(set (match_dup 0)
776         (zero_extend:EXTHI (match_dup 1)))
777    (set (match_dup 2)
778         (compare:CC (match_dup 0)
779                     (const_int 0)))]
780   ""
781   [(set_attr "type" "logical")
782    (set_attr "dot" "yes")
783    (set_attr "length" "4,8")])
785 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
786   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
787         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
788                     (const_int 0)))
789    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
790         (zero_extend:EXTHI (match_dup 1)))]
791   "rs6000_gen_cell_microcode"
792   "@
793    andi. %0,%1,0xffff
794    #"
795   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
796   [(set (match_dup 0)
797         (zero_extend:EXTHI (match_dup 1)))
798    (set (match_dup 2)
799         (compare:CC (match_dup 0)
800                     (const_int 0)))]
801   ""
802   [(set_attr "type" "logical")
803    (set_attr "dot" "yes")
804    (set_attr "length" "4,8")])
807 (define_insn "zero_extendsi<mode>2"
808   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
809         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
810   ""
811   "@
812    lwz%U1%X1 %0,%1
813    rldicl %0,%1,0,32
814    mtvsrwz %x0,%1
815    lfiwzx %0,%y1
816    lxsiwzx %x0,%y1"
817   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
819 (define_insn_and_split "*zero_extendsi<mode>2_dot"
820   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
821         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
822                     (const_int 0)))
823    (clobber (match_scratch:EXTSI 0 "=r,r"))]
824   "rs6000_gen_cell_microcode"
825   "@
826    rldicl. %0,%1,0,32
827    #"
828   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
829   [(set (match_dup 0)
830         (zero_extend:DI (match_dup 1)))
831    (set (match_dup 2)
832         (compare:CC (match_dup 0)
833                     (const_int 0)))]
834   ""
835   [(set_attr "type" "shift")
836    (set_attr "dot" "yes")
837    (set_attr "length" "4,8")])
839 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
840   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
841         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
842                     (const_int 0)))
843    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
844         (zero_extend:EXTSI (match_dup 1)))]
845   "rs6000_gen_cell_microcode"
846   "@
847    rldicl. %0,%1,0,32
848    #"
849   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
850   [(set (match_dup 0)
851         (zero_extend:EXTSI (match_dup 1)))
852    (set (match_dup 2)
853         (compare:CC (match_dup 0)
854                     (const_int 0)))]
855   ""
856   [(set_attr "type" "shift")
857    (set_attr "dot" "yes")
858    (set_attr "length" "4,8")])
861 (define_insn "extendqi<mode>2"
862   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
863         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
864   ""
865   "extsb %0,%1"
866   [(set_attr "type" "exts")])
868 (define_insn_and_split "*extendqi<mode>2_dot"
869   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
870         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
871                     (const_int 0)))
872    (clobber (match_scratch:EXTQI 0 "=r,r"))]
873   "rs6000_gen_cell_microcode"
874   "@
875    extsb. %0,%1
876    #"
877   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
878   [(set (match_dup 0)
879         (sign_extend:EXTQI (match_dup 1)))
880    (set (match_dup 2)
881         (compare:CC (match_dup 0)
882                     (const_int 0)))]
883   ""
884   [(set_attr "type" "exts")
885    (set_attr "dot" "yes")
886    (set_attr "length" "4,8")])
888 (define_insn_and_split "*extendqi<mode>2_dot2"
889   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
890         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
891                     (const_int 0)))
892    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
893         (sign_extend:EXTQI (match_dup 1)))]
894   "rs6000_gen_cell_microcode"
895   "@
896    extsb. %0,%1
897    #"
898   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
899   [(set (match_dup 0)
900         (sign_extend:EXTQI (match_dup 1)))
901    (set (match_dup 2)
902         (compare:CC (match_dup 0)
903                     (const_int 0)))]
904   ""
905   [(set_attr "type" "exts")
906    (set_attr "dot" "yes")
907    (set_attr "length" "4,8")])
910 (define_expand "extendhi<mode>2"
911   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
912         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
913   ""
914   "")
916 (define_insn "*extendhi<mode>2"
917   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
918         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
919   "rs6000_gen_cell_microcode"
920   "@
921    lha%U1%X1 %0,%1
922    extsh %0,%1"
923   [(set_attr "type" "load,exts")
924    (set_attr "sign_extend" "yes")])
926 (define_insn "*extendhi<mode>2_noload"
927   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
928         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
929   "!rs6000_gen_cell_microcode"
930   "extsh %0,%1"
931   [(set_attr "type" "exts")])
933 (define_insn_and_split "*extendhi<mode>2_dot"
934   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
935         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
936                     (const_int 0)))
937    (clobber (match_scratch:EXTHI 0 "=r,r"))]
938   "rs6000_gen_cell_microcode"
939   "@
940    extsh. %0,%1
941    #"
942   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
943   [(set (match_dup 0)
944         (sign_extend:EXTHI (match_dup 1)))
945    (set (match_dup 2)
946         (compare:CC (match_dup 0)
947                     (const_int 0)))]
948   ""
949   [(set_attr "type" "exts")
950    (set_attr "dot" "yes")
951    (set_attr "length" "4,8")])
953 (define_insn_and_split "*extendhi<mode>2_dot2"
954   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
955         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
956                     (const_int 0)))
957    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
958         (sign_extend:EXTHI (match_dup 1)))]
959   "rs6000_gen_cell_microcode"
960   "@
961    extsh. %0,%1
962    #"
963   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
964   [(set (match_dup 0)
965         (sign_extend:EXTHI (match_dup 1)))
966    (set (match_dup 2)
967         (compare:CC (match_dup 0)
968                     (const_int 0)))]
969   ""
970   [(set_attr "type" "exts")
971    (set_attr "dot" "yes")
972    (set_attr "length" "4,8")])
975 (define_insn "extendsi<mode>2"
976   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
977         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
978   ""
979   "@
980    lwa%U1%X1 %0,%1
981    extsw %0,%1
982    mtvsrwa %x0,%1
983    lfiwax %0,%y1
984    lxsiwax %x0,%y1"
985   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
986    (set_attr "sign_extend" "yes")])
988 (define_insn_and_split "*extendsi<mode>2_dot"
989   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
990         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
991                     (const_int 0)))
992    (clobber (match_scratch:EXTSI 0 "=r,r"))]
993   "rs6000_gen_cell_microcode"
994   "@
995    extsw. %0,%1
996    #"
997   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
998   [(set (match_dup 0)
999         (sign_extend:EXTSI (match_dup 1)))
1000    (set (match_dup 2)
1001         (compare:CC (match_dup 0)
1002                     (const_int 0)))]
1003   ""
1004   [(set_attr "type" "exts")
1005    (set_attr "dot" "yes")
1006    (set_attr "length" "4,8")])
1008 (define_insn_and_split "*extendsi<mode>2_dot2"
1009   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1010         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1011                     (const_int 0)))
1012    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1013         (sign_extend:EXTSI (match_dup 1)))]
1014   "rs6000_gen_cell_microcode"
1015   "@
1016    extsw. %0,%1
1017    #"
1018   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1019   [(set (match_dup 0)
1020         (sign_extend:EXTSI (match_dup 1)))
1021    (set (match_dup 2)
1022         (compare:CC (match_dup 0)
1023                     (const_int 0)))]
1024   ""
1025   [(set_attr "type" "exts")
1026    (set_attr "dot" "yes")
1027    (set_attr "length" "4,8")])
1029 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1031 (define_insn "*macchwc"
1032   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1033         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1034                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1035                                        (const_int 16))
1036                                       (sign_extend:SI
1037                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1038                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1039                     (const_int 0)))
1040    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1041         (plus:SI (mult:SI (ashiftrt:SI
1042                            (match_dup 2)
1043                            (const_int 16))
1044                           (sign_extend:SI
1045                            (match_dup 1)))
1046                  (match_dup 4)))]
1047   "TARGET_MULHW"
1048   "macchw. %0,%1,%2"
1049   [(set_attr "type" "halfmul")])
1051 (define_insn "*macchw"
1052   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1053         (plus:SI (mult:SI (ashiftrt:SI
1054                            (match_operand:SI 2 "gpc_reg_operand" "r")
1055                            (const_int 16))
1056                           (sign_extend:SI
1057                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1058                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1059   "TARGET_MULHW"
1060   "macchw %0,%1,%2"
1061   [(set_attr "type" "halfmul")])
1063 (define_insn "*macchwuc"
1064   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1066                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1067                                        (const_int 16))
1068                                       (zero_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 (lshiftrt:SI
1074                            (match_dup 2)
1075                            (const_int 16))
1076                           (zero_extend:SI
1077                            (match_dup 1)))
1078                  (match_dup 4)))]
1079   "TARGET_MULHW"
1080   "macchwu. %0,%1,%2"
1081   [(set_attr "type" "halfmul")])
1083 (define_insn "*macchwu"
1084   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1085         (plus:SI (mult:SI (lshiftrt:SI
1086                            (match_operand:SI 2 "gpc_reg_operand" "r")
1087                            (const_int 16))
1088                           (zero_extend:SI
1089                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1090                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1091   "TARGET_MULHW"
1092   "macchwu %0,%1,%2"
1093   [(set_attr "type" "halfmul")])
1095 (define_insn "*machhwc"
1096   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1097         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1098                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1099                                        (const_int 16))
1100                                       (ashiftrt:SI
1101                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1102                                        (const_int 16)))
1103                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1104                     (const_int 0)))
1105    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1106         (plus:SI (mult:SI (ashiftrt:SI
1107                            (match_dup 1)
1108                            (const_int 16))
1109                           (ashiftrt:SI
1110                            (match_dup 2)
1111                            (const_int 16)))
1112                  (match_dup 4)))]
1113   "TARGET_MULHW"
1114   "machhw. %0,%1,%2"
1115   [(set_attr "type" "halfmul")])
1117 (define_insn "*machhw"
1118   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1119         (plus:SI (mult:SI (ashiftrt:SI
1120                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1121                            (const_int 16))
1122                           (ashiftrt:SI
1123                            (match_operand:SI 2 "gpc_reg_operand" "r")
1124                            (const_int 16)))
1125                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1126   "TARGET_MULHW"
1127   "machhw %0,%1,%2"
1128   [(set_attr "type" "halfmul")])
1130 (define_insn "*machhwuc"
1131   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1132         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1133                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1134                                        (const_int 16))
1135                                       (lshiftrt:SI
1136                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1137                                        (const_int 16)))
1138                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1139                     (const_int 0)))
1140    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1141         (plus:SI (mult:SI (lshiftrt:SI
1142                            (match_dup 1)
1143                            (const_int 16))
1144                           (lshiftrt:SI
1145                            (match_dup 2)
1146                            (const_int 16)))
1147                  (match_dup 4)))]
1148   "TARGET_MULHW"
1149   "machhwu. %0,%1,%2"
1150   [(set_attr "type" "halfmul")])
1152 (define_insn "*machhwu"
1153   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154         (plus:SI (mult:SI (lshiftrt:SI
1155                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1156                            (const_int 16))
1157                           (lshiftrt:SI
1158                            (match_operand:SI 2 "gpc_reg_operand" "r")
1159                            (const_int 16)))
1160                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1161   "TARGET_MULHW"
1162   "machhwu %0,%1,%2"
1163   [(set_attr "type" "halfmul")])
1165 (define_insn "*maclhwc"
1166   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1167         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1168                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1169                                       (sign_extend:SI
1170                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1171                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1172                     (const_int 0)))
1173    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1174         (plus:SI (mult:SI (sign_extend:SI
1175                            (match_dup 1))
1176                           (sign_extend:SI
1177                            (match_dup 2)))
1178                  (match_dup 4)))]
1179   "TARGET_MULHW"
1180   "maclhw. %0,%1,%2"
1181   [(set_attr "type" "halfmul")])
1183 (define_insn "*maclhw"
1184   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1185         (plus:SI (mult:SI (sign_extend:SI
1186                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1187                           (sign_extend:SI
1188                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1189                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1190   "TARGET_MULHW"
1191   "maclhw %0,%1,%2"
1192   [(set_attr "type" "halfmul")])
1194 (define_insn "*maclhwuc"
1195   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1196         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1197                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1198                                       (zero_extend:SI
1199                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1200                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1201                     (const_int 0)))
1202    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1203         (plus:SI (mult:SI (zero_extend:SI
1204                            (match_dup 1))
1205                           (zero_extend:SI
1206                            (match_dup 2)))
1207                  (match_dup 4)))]
1208   "TARGET_MULHW"
1209   "maclhwu. %0,%1,%2"
1210   [(set_attr "type" "halfmul")])
1212 (define_insn "*maclhwu"
1213   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214         (plus:SI (mult:SI (zero_extend:SI
1215                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1216                           (zero_extend:SI
1217                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1218                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1219   "TARGET_MULHW"
1220   "maclhwu %0,%1,%2"
1221   [(set_attr "type" "halfmul")])
1223 (define_insn "*nmacchwc"
1224   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1225         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1226                               (mult:SI (ashiftrt:SI
1227                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1228                                         (const_int 16))
1229                                        (sign_extend:SI
1230                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1231                     (const_int 0)))
1232    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1233         (minus:SI (match_dup 4)
1234                   (mult:SI (ashiftrt:SI
1235                             (match_dup 2)
1236                             (const_int 16))
1237                            (sign_extend:SI
1238                             (match_dup 1)))))]
1239   "TARGET_MULHW"
1240   "nmacchw. %0,%1,%2"
1241   [(set_attr "type" "halfmul")])
1243 (define_insn "*nmacchw"
1244   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1246                   (mult:SI (ashiftrt:SI
1247                             (match_operand:SI 2 "gpc_reg_operand" "r")
1248                             (const_int 16))
1249                            (sign_extend:SI
1250                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1251   "TARGET_MULHW"
1252   "nmacchw %0,%1,%2"
1253   [(set_attr "type" "halfmul")])
1255 (define_insn "*nmachhwc"
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 1 "gpc_reg_operand" "%r")
1260                                         (const_int 16))
1261                                        (ashiftrt:SI
1262                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1263                                         (const_int 16))))
1264                     (const_int 0)))
1265    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1266         (minus:SI (match_dup 4)
1267                   (mult:SI (ashiftrt:SI
1268                             (match_dup 1)
1269                             (const_int 16))
1270                            (ashiftrt:SI
1271                             (match_dup 2)
1272                             (const_int 16)))))]
1273   "TARGET_MULHW"
1274   "nmachhw. %0,%1,%2"
1275   [(set_attr "type" "halfmul")])
1277 (define_insn "*nmachhw"
1278   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1279         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1280                   (mult:SI (ashiftrt:SI
1281                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1282                             (const_int 16))
1283                            (ashiftrt:SI
1284                             (match_operand:SI 2 "gpc_reg_operand" "r")
1285                             (const_int 16)))))]
1286   "TARGET_MULHW"
1287   "nmachhw %0,%1,%2"
1288   [(set_attr "type" "halfmul")])
1290 (define_insn "*nmaclhwc"
1291   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1293                               (mult:SI (sign_extend:SI
1294                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1295                                        (sign_extend:SI
1296                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1297                     (const_int 0)))
1298    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299         (minus:SI (match_dup 4)
1300                   (mult:SI (sign_extend:SI
1301                             (match_dup 1))
1302                            (sign_extend:SI
1303                             (match_dup 2)))))]
1304   "TARGET_MULHW"
1305   "nmaclhw. %0,%1,%2"
1306   [(set_attr "type" "halfmul")])
1308 (define_insn "*nmaclhw"
1309   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1310         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1311                   (mult:SI (sign_extend:SI
1312                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1313                            (sign_extend:SI
1314                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1315   "TARGET_MULHW"
1316   "nmaclhw %0,%1,%2"
1317   [(set_attr "type" "halfmul")])
1319 (define_insn "*mulchwc"
1320   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1321         (compare:CC (mult:SI (ashiftrt:SI
1322                               (match_operand:SI 2 "gpc_reg_operand" "r")
1323                               (const_int 16))
1324                              (sign_extend:SI
1325                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1326                     (const_int 0)))
1327    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328         (mult:SI (ashiftrt:SI
1329                   (match_dup 2)
1330                   (const_int 16))
1331                  (sign_extend:SI
1332                   (match_dup 1))))]
1333   "TARGET_MULHW"
1334   "mulchw. %0,%1,%2"
1335   [(set_attr "type" "halfmul")])
1337 (define_insn "*mulchw"
1338   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1339         (mult:SI (ashiftrt:SI
1340                   (match_operand:SI 2 "gpc_reg_operand" "r")
1341                   (const_int 16))
1342                  (sign_extend:SI
1343                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1344   "TARGET_MULHW"
1345   "mulchw %0,%1,%2"
1346   [(set_attr "type" "halfmul")])
1348 (define_insn "*mulchwuc"
1349   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1350         (compare:CC (mult:SI (lshiftrt:SI
1351                               (match_operand:SI 2 "gpc_reg_operand" "r")
1352                               (const_int 16))
1353                              (zero_extend:SI
1354                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1355                     (const_int 0)))
1356    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357         (mult:SI (lshiftrt:SI
1358                   (match_dup 2)
1359                   (const_int 16))
1360                  (zero_extend:SI
1361                   (match_dup 1))))]
1362   "TARGET_MULHW"
1363   "mulchwu. %0,%1,%2"
1364   [(set_attr "type" "halfmul")])
1366 (define_insn "*mulchwu"
1367   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1368         (mult:SI (lshiftrt:SI
1369                   (match_operand:SI 2 "gpc_reg_operand" "r")
1370                   (const_int 16))
1371                  (zero_extend:SI
1372                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1373   "TARGET_MULHW"
1374   "mulchwu %0,%1,%2"
1375   [(set_attr "type" "halfmul")])
1377 (define_insn "*mulhhwc"
1378   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1379         (compare:CC (mult:SI (ashiftrt:SI
1380                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1381                               (const_int 16))
1382                              (ashiftrt:SI
1383                               (match_operand:SI 2 "gpc_reg_operand" "r")
1384                               (const_int 16)))
1385                     (const_int 0)))
1386    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1387         (mult:SI (ashiftrt:SI
1388                   (match_dup 1)
1389                   (const_int 16))
1390                  (ashiftrt:SI
1391                   (match_dup 2)
1392                   (const_int 16))))]
1393   "TARGET_MULHW"
1394   "mulhhw. %0,%1,%2"
1395   [(set_attr "type" "halfmul")])
1397 (define_insn "*mulhhw"
1398   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399         (mult:SI (ashiftrt:SI
1400                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1401                   (const_int 16))
1402                  (ashiftrt:SI
1403                   (match_operand:SI 2 "gpc_reg_operand" "r")
1404                   (const_int 16))))]
1405   "TARGET_MULHW"
1406   "mulhhw %0,%1,%2"
1407   [(set_attr "type" "halfmul")])
1409 (define_insn "*mulhhwuc"
1410   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411         (compare:CC (mult:SI (lshiftrt:SI
1412                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1413                               (const_int 16))
1414                              (lshiftrt: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 (lshiftrt:SI
1420                   (match_dup 1)
1421                   (const_int 16))
1422                  (lshiftrt:SI
1423                   (match_dup 2)
1424                   (const_int 16))))]
1425   "TARGET_MULHW"
1426   "mulhhwu. %0,%1,%2"
1427   [(set_attr "type" "halfmul")])
1429 (define_insn "*mulhhwu"
1430   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1431         (mult:SI (lshiftrt:SI
1432                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1433                   (const_int 16))
1434                  (lshiftrt:SI
1435                   (match_operand:SI 2 "gpc_reg_operand" "r")
1436                   (const_int 16))))]
1437   "TARGET_MULHW"
1438   "mulhhwu %0,%1,%2"
1439   [(set_attr "type" "halfmul")])
1441 (define_insn "*mullhwc"
1442   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1443         (compare:CC (mult:SI (sign_extend:SI
1444                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1445                              (sign_extend:SI
1446                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1447                     (const_int 0)))
1448    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449         (mult:SI (sign_extend:SI
1450                   (match_dup 1))
1451                  (sign_extend:SI
1452                   (match_dup 2))))]
1453   "TARGET_MULHW"
1454   "mullhw. %0,%1,%2"
1455   [(set_attr "type" "halfmul")])
1457 (define_insn "*mullhw"
1458   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1459         (mult:SI (sign_extend:SI
1460                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1461                  (sign_extend:SI
1462                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1463   "TARGET_MULHW"
1464   "mullhw %0,%1,%2"
1465   [(set_attr "type" "halfmul")])
1467 (define_insn "*mullhwuc"
1468   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1469         (compare:CC (mult:SI (zero_extend:SI
1470                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1471                              (zero_extend:SI
1472                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1473                     (const_int 0)))
1474    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1475         (mult:SI (zero_extend:SI
1476                   (match_dup 1))
1477                  (zero_extend:SI
1478                   (match_dup 2))))]
1479   "TARGET_MULHW"
1480   "mullhwu. %0,%1,%2"
1481   [(set_attr "type" "halfmul")])
1483 (define_insn "*mullhwu"
1484   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1485         (mult:SI (zero_extend:SI
1486                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1487                  (zero_extend:SI
1488                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1489   "TARGET_MULHW"
1490   "mullhwu %0,%1,%2"
1491   [(set_attr "type" "halfmul")])
1493 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1494 (define_insn "dlmzb"
1495   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1496         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1497                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1498                    UNSPEC_DLMZB_CR))
1499    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1500         (unspec:SI [(match_dup 1)
1501                     (match_dup 2)]
1502                    UNSPEC_DLMZB))]
1503   "TARGET_DLMZB"
1504   "dlmzb. %0,%1,%2")
1506 (define_expand "strlensi"
1507   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1508         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1509                     (match_operand:QI 2 "const_int_operand" "")
1510                     (match_operand 3 "const_int_operand" "")]
1511                    UNSPEC_DLMZB_STRLEN))
1512    (clobber (match_scratch:CC 4 "=x"))]
1513   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1515   rtx result = operands[0];
1516   rtx src = operands[1];
1517   rtx search_char = operands[2];
1518   rtx align = operands[3];
1519   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1520   rtx loop_label, end_label, mem, cr0, cond;
1521   if (search_char != const0_rtx
1522       || GET_CODE (align) != CONST_INT
1523       || INTVAL (align) < 8)
1524         FAIL;
1525   word1 = gen_reg_rtx (SImode);
1526   word2 = gen_reg_rtx (SImode);
1527   scratch_dlmzb = gen_reg_rtx (SImode);
1528   scratch_string = gen_reg_rtx (Pmode);
1529   loop_label = gen_label_rtx ();
1530   end_label = gen_label_rtx ();
1531   addr = force_reg (Pmode, XEXP (src, 0));
1532   emit_move_insn (scratch_string, addr);
1533   emit_label (loop_label);
1534   mem = change_address (src, SImode, scratch_string);
1535   emit_move_insn (word1, mem);
1536   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1537   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1538   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1539   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1540   emit_jump_insn (gen_rtx_SET (pc_rtx,
1541                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1542                                                      cond,
1543                                                      gen_rtx_LABEL_REF
1544                                                        (VOIDmode,
1545                                                         end_label),
1546                                                      pc_rtx)));
1547   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1548   emit_jump_insn (gen_rtx_SET (pc_rtx,
1549                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1550   emit_barrier ();
1551   emit_label (end_label);
1552   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1553   emit_insn (gen_subsi3 (result, scratch_string, addr));
1554   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1555   DONE;
1558 ;; Fixed-point arithmetic insns.
1560 (define_expand "add<mode>3"
1561   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1562         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1563                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1564   ""
1566   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1567     {
1568       rtx lo0 = gen_lowpart (SImode, operands[0]);
1569       rtx lo1 = gen_lowpart (SImode, operands[1]);
1570       rtx lo2 = gen_lowpart (SImode, operands[2]);
1571       rtx hi0 = gen_highpart (SImode, operands[0]);
1572       rtx hi1 = gen_highpart (SImode, operands[1]);
1573       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1575       if (!reg_or_short_operand (lo2, SImode))
1576         lo2 = force_reg (SImode, lo2);
1577       if (!adde_operand (hi2, SImode))
1578         hi2 = force_reg (SImode, hi2);
1580       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1581       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1582       DONE;
1583     }
1585   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1586     {
1587       rtx tmp = ((!can_create_pseudo_p ()
1588                   || rtx_equal_p (operands[0], operands[1]))
1589                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1591       HOST_WIDE_INT val = INTVAL (operands[2]);
1592       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1593       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1595       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1596         FAIL;
1598       /* The ordering here is important for the prolog expander.
1599          When space is allocated from the stack, adding 'low' first may
1600          produce a temporary deallocation (which would be bad).  */
1601       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1602       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1603       DONE;
1604     }
1607 (define_insn "*add<mode>3"
1608   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1609         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1610                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1611   ""
1612   "@
1613    add %0,%1,%2
1614    addi %0,%1,%2
1615    addis %0,%1,%v2"
1616   [(set_attr "type" "add")])
1618 (define_insn "addsi3_high"
1619   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1620         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1621                  (high:SI (match_operand 2 "" ""))))]
1622   "TARGET_MACHO && !TARGET_64BIT"
1623   "addis %0,%1,ha16(%2)"
1624   [(set_attr "type" "add")])
1626 (define_insn_and_split "*add<mode>3_dot"
1627   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1628         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1629                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1630                     (const_int 0)))
1631    (clobber (match_scratch:GPR 0 "=r,r"))]
1632   "<MODE>mode == Pmode"
1633   "@
1634    add. %0,%1,%2
1635    #"
1636   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1637   [(set (match_dup 0)
1638         (plus:GPR (match_dup 1)
1639                  (match_dup 2)))
1640    (set (match_dup 3)
1641         (compare:CC (match_dup 0)
1642                     (const_int 0)))]
1643   ""
1644   [(set_attr "type" "add")
1645    (set_attr "dot" "yes")
1646    (set_attr "length" "4,8")])
1648 (define_insn_and_split "*add<mode>3_dot2"
1649   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1650         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1651                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1652                     (const_int 0)))
1653    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1654         (plus:GPR (match_dup 1)
1655                   (match_dup 2)))]
1656   "<MODE>mode == Pmode"
1657   "@
1658    add. %0,%1,%2
1659    #"
1660   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1661   [(set (match_dup 0)
1662         (plus:GPR (match_dup 1)
1663                   (match_dup 2)))
1664    (set (match_dup 3)
1665         (compare:CC (match_dup 0)
1666                     (const_int 0)))]
1667   ""
1668   [(set_attr "type" "add")
1669    (set_attr "dot" "yes")
1670    (set_attr "length" "4,8")])
1672 (define_insn_and_split "*add<mode>3_imm_dot"
1673   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1674         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1675                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1676                     (const_int 0)))
1677    (clobber (match_scratch:GPR 0 "=r,r"))
1678    (clobber (reg:GPR CA_REGNO))]
1679   "<MODE>mode == Pmode"
1680   "@
1681    addic. %0,%1,%2
1682    #"
1683   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1684   [(set (match_dup 0)
1685         (plus:GPR (match_dup 1)
1686                   (match_dup 2)))
1687    (set (match_dup 3)
1688         (compare:CC (match_dup 0)
1689                     (const_int 0)))]
1690   ""
1691   [(set_attr "type" "add")
1692    (set_attr "dot" "yes")
1693    (set_attr "length" "4,8")])
1695 (define_insn_and_split "*add<mode>3_imm_dot2"
1696   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1697         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1698                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1699                     (const_int 0)))
1700    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1701         (plus:GPR (match_dup 1)
1702                   (match_dup 2)))
1703    (clobber (reg:GPR CA_REGNO))]
1704   "<MODE>mode == Pmode"
1705   "@
1706    addic. %0,%1,%2
1707    #"
1708   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1709   [(set (match_dup 0)
1710         (plus:GPR (match_dup 1)
1711                   (match_dup 2)))
1712    (set (match_dup 3)
1713         (compare:CC (match_dup 0)
1714                     (const_int 0)))]
1715   ""
1716   [(set_attr "type" "add")
1717    (set_attr "dot" "yes")
1718    (set_attr "length" "4,8")])
1720 ;; Split an add that we can't do in one insn into two insns, each of which
1721 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1722 ;; add should be last in case the result gets used in an address.
1724 (define_split
1725   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1726         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1727                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1728   ""
1729   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1730    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1732   HOST_WIDE_INT val = INTVAL (operands[2]);
1733   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1734   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1736   operands[4] = GEN_INT (low);
1737   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1738     operands[3] = GEN_INT (rest);
1739   else if (can_create_pseudo_p ())
1740     {
1741       operands[3] = gen_reg_rtx (DImode);
1742       emit_move_insn (operands[3], operands[2]);
1743       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1744       DONE;
1745     }
1746   else
1747     FAIL;
1751 (define_insn "add<mode>3_carry"
1752   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1753         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1754                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1755    (set (reg:P CA_REGNO)
1756         (ltu:P (plus:P (match_dup 1)
1757                        (match_dup 2))
1758                (match_dup 1)))]
1759   ""
1760   "add%I2c %0,%1,%2"
1761   [(set_attr "type" "add")])
1763 (define_insn "*add<mode>3_imm_carry_pos"
1764   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1765         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1766                 (match_operand:P 2 "short_cint_operand" "n")))
1767    (set (reg:P CA_REGNO)
1768         (geu:P (match_dup 1)
1769                (match_operand:P 3 "const_int_operand" "n")))]
1770   "INTVAL (operands[2]) > 0
1771    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1772   "addic %0,%1,%2"
1773   [(set_attr "type" "add")])
1775 (define_insn "*add<mode>3_imm_carry_0"
1776   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1777         (match_operand:P 1 "gpc_reg_operand" "r"))
1778    (set (reg:P CA_REGNO)
1779         (const_int 0))]
1780   ""
1781   "addic %0,%1,0"
1782   [(set_attr "type" "add")])
1784 (define_insn "*add<mode>3_imm_carry_m1"
1785   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1786         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1787                 (const_int -1)))
1788    (set (reg:P CA_REGNO)
1789         (ne:P (match_dup 1)
1790               (const_int 0)))]
1791   ""
1792   "addic %0,%1,-1"
1793   [(set_attr "type" "add")])
1795 (define_insn "*add<mode>3_imm_carry_neg"
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         (gtu: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]) == -1"
1804   "addic %0,%1,%2"
1805   [(set_attr "type" "add")])
1808 (define_expand "add<mode>3_carry_in"
1809   [(parallel [
1810      (set (match_operand:GPR 0 "gpc_reg_operand")
1811           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1812                               (match_operand:GPR 2 "adde_operand"))
1813                     (reg:GPR CA_REGNO)))
1814      (clobber (reg:GPR CA_REGNO))])]
1815   ""
1817   if (operands[2] == const0_rtx)
1818     {
1819       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1820       DONE;
1821     }
1822   if (operands[2] == constm1_rtx)
1823     {
1824       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1825       DONE;
1826     }
1829 (define_insn "*add<mode>3_carry_in_internal"
1830   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1831         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1832                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1833                   (reg:GPR CA_REGNO)))
1834    (clobber (reg:GPR CA_REGNO))]
1835   ""
1836   "adde %0,%1,%2"
1837   [(set_attr "type" "add")])
1839 (define_insn "add<mode>3_carry_in_0"
1840   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1841         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1842                   (reg:GPR CA_REGNO)))
1843    (clobber (reg:GPR CA_REGNO))]
1844   ""
1845   "addze %0,%1"
1846   [(set_attr "type" "add")])
1848 (define_insn "add<mode>3_carry_in_m1"
1849   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1850         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1851                             (reg:GPR CA_REGNO))
1852                   (const_int -1)))
1853    (clobber (reg:GPR CA_REGNO))]
1854   ""
1855   "addme %0,%1"
1856   [(set_attr "type" "add")])
1859 (define_expand "one_cmpl<mode>2"
1860   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1861         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1862   ""
1864   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1865     {
1866       rs6000_split_logical (operands, NOT, false, false, false);
1867       DONE;
1868     }
1871 (define_insn "*one_cmpl<mode>2"
1872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1873         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1874   ""
1875   "not %0,%1")
1877 (define_insn_and_split "*one_cmpl<mode>2_dot"
1878   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1879         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1880                     (const_int 0)))
1881    (clobber (match_scratch:GPR 0 "=r,r"))]
1882   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1883   "@
1884    not. %0,%1
1885    #"
1886   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1887   [(set (match_dup 0)
1888         (not:GPR (match_dup 1)))
1889    (set (match_dup 2)
1890         (compare:CC (match_dup 0)
1891                     (const_int 0)))]
1892   ""
1893   [(set_attr "type" "logical")
1894    (set_attr "dot" "yes")
1895    (set_attr "length" "4,8")])
1897 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1898   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1899         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1900                     (const_int 0)))
1901    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1902         (not:GPR (match_dup 1)))]
1903   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1904   "@
1905    not. %0,%1
1906    #"
1907   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1908   [(set (match_dup 0)
1909         (not:GPR (match_dup 1)))
1910    (set (match_dup 2)
1911         (compare:CC (match_dup 0)
1912                     (const_int 0)))]
1913   ""
1914   [(set_attr "type" "logical")
1915    (set_attr "dot" "yes")
1916    (set_attr "length" "4,8")])
1919 (define_expand "sub<mode>3"
1920   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1921         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1922                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1923   ""
1925   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1926     {
1927       rtx lo0 = gen_lowpart (SImode, operands[0]);
1928       rtx lo1 = gen_lowpart (SImode, operands[1]);
1929       rtx lo2 = gen_lowpart (SImode, operands[2]);
1930       rtx hi0 = gen_highpart (SImode, operands[0]);
1931       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1932       rtx hi2 = gen_highpart (SImode, operands[2]);
1934       if (!reg_or_short_operand (lo1, SImode))
1935         lo1 = force_reg (SImode, lo1);
1936       if (!adde_operand (hi1, SImode))
1937         hi1 = force_reg (SImode, hi1);
1939       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1940       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1941       DONE;
1942     }
1944   if (short_cint_operand (operands[1], <MODE>mode))
1945     {
1946       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1947       DONE;
1948     }
1951 (define_insn "*subf<mode>3"
1952   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1953         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1954                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1955   ""
1956   "subf %0,%1,%2"
1957   [(set_attr "type" "add")])
1959 (define_insn_and_split "*subf<mode>3_dot"
1960   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1961         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1962                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1963                     (const_int 0)))
1964    (clobber (match_scratch:GPR 0 "=r,r"))]
1965   "<MODE>mode == Pmode"
1966   "@
1967    subf. %0,%1,%2
1968    #"
1969   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1970   [(set (match_dup 0)
1971         (minus:GPR (match_dup 2)
1972                    (match_dup 1)))
1973    (set (match_dup 3)
1974         (compare:CC (match_dup 0)
1975                     (const_int 0)))]
1976   ""
1977   [(set_attr "type" "add")
1978    (set_attr "dot" "yes")
1979    (set_attr "length" "4,8")])
1981 (define_insn_and_split "*subf<mode>3_dot2"
1982   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1983         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1984                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1985                     (const_int 0)))
1986    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1987         (minus:GPR (match_dup 2)
1988                    (match_dup 1)))]
1989   "<MODE>mode == Pmode"
1990   "@
1991    subf. %0,%1,%2
1992    #"
1993   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1994   [(set (match_dup 0)
1995         (minus:GPR (match_dup 2)
1996                    (match_dup 1)))
1997    (set (match_dup 3)
1998         (compare:CC (match_dup 0)
1999                     (const_int 0)))]
2000   ""
2001   [(set_attr "type" "add")
2002    (set_attr "dot" "yes")
2003    (set_attr "length" "4,8")])
2005 (define_insn "subf<mode>3_imm"
2006   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2007         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2008                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2009    (clobber (reg:GPR CA_REGNO))]
2010   ""
2011   "subfic %0,%1,%2"
2012   [(set_attr "type" "add")])
2015 (define_insn "subf<mode>3_carry"
2016   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2017         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2018                  (match_operand:P 1 "gpc_reg_operand" "r")))
2019    (set (reg:P CA_REGNO)
2020         (leu:P (match_dup 1)
2021                (match_dup 2)))]
2022   ""
2023   "subf%I2c %0,%1,%2"
2024   [(set_attr "type" "add")])
2026 (define_insn "*subf<mode>3_imm_carry_0"
2027   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2028         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2029    (set (reg:P CA_REGNO)
2030         (eq:P (match_dup 1)
2031               (const_int 0)))]
2032   ""
2033   "subfic %0,%1,0"
2034   [(set_attr "type" "add")])
2036 (define_insn "*subf<mode>3_imm_carry_m1"
2037   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2038         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2039    (set (reg:P CA_REGNO)
2040         (const_int 1))]
2041   ""
2042   "subfic %0,%1,-1"
2043   [(set_attr "type" "add")])
2046 (define_expand "subf<mode>3_carry_in"
2047   [(parallel [
2048      (set (match_operand:GPR 0 "gpc_reg_operand")
2049           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2050                               (reg:GPR CA_REGNO))
2051                     (match_operand:GPR 2 "adde_operand")))
2052      (clobber (reg:GPR CA_REGNO))])]
2053   ""
2055   if (operands[2] == const0_rtx)
2056     {
2057       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2058       DONE;
2059     }
2060   if (operands[2] == constm1_rtx)
2061     {
2062       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2063       DONE;
2064     }
2067 (define_insn "*subf<mode>3_carry_in_internal"
2068   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2070                             (reg:GPR CA_REGNO))
2071                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2072    (clobber (reg:GPR CA_REGNO))]
2073   ""
2074   "subfe %0,%1,%2"
2075   [(set_attr "type" "add")])
2077 (define_insn "subf<mode>3_carry_in_0"
2078   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2079         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2080                   (reg:GPR CA_REGNO)))
2081    (clobber (reg:GPR CA_REGNO))]
2082   ""
2083   "subfze %0,%1"
2084   [(set_attr "type" "add")])
2086 (define_insn "subf<mode>3_carry_in_m1"
2087   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2089                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2090                   (const_int -2)))
2091    (clobber (reg:GPR CA_REGNO))]
2092   ""
2093   "subfme %0,%1"
2094   [(set_attr "type" "add")])
2096 (define_insn "subf<mode>3_carry_in_xx"
2097   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098         (plus:GPR (reg:GPR CA_REGNO)
2099                   (const_int -1)))
2100    (clobber (reg:GPR CA_REGNO))]
2101   ""
2102   "subfe %0,%0,%0"
2103   [(set_attr "type" "add")])
2106 (define_insn "neg<mode>2"
2107   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2108         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2109   ""
2110   "neg %0,%1"
2111   [(set_attr "type" "add")])
2113 (define_insn_and_split "*neg<mode>2_dot"
2114   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2115         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2116                     (const_int 0)))
2117    (clobber (match_scratch:GPR 0 "=r,r"))]
2118   "<MODE>mode == Pmode"
2119   "@
2120    neg. %0,%1
2121    #"
2122   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2123   [(set (match_dup 0)
2124         (neg:GPR (match_dup 1)))
2125    (set (match_dup 2)
2126         (compare:CC (match_dup 0)
2127                     (const_int 0)))]
2128   ""
2129   [(set_attr "type" "add")
2130    (set_attr "dot" "yes")
2131    (set_attr "length" "4,8")])
2133 (define_insn_and_split "*neg<mode>2_dot2"
2134   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2135         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2136                     (const_int 0)))
2137    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2138         (neg:GPR (match_dup 1)))]
2139   "<MODE>mode == Pmode"
2140   "@
2141    neg. %0,%1
2142    #"
2143   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2144   [(set (match_dup 0)
2145         (neg:GPR (match_dup 1)))
2146    (set (match_dup 2)
2147         (compare:CC (match_dup 0)
2148                     (const_int 0)))]
2149   ""
2150   [(set_attr "type" "add")
2151    (set_attr "dot" "yes")
2152    (set_attr "length" "4,8")])
2155 (define_insn "clz<mode>2"
2156   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2157         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2158   ""
2159   "cntlz<wd> %0,%1"
2160   [(set_attr "type" "cntlz")])
2162 (define_expand "ctz<mode>2"
2163   [(set (match_dup 2)
2164         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2165    (set (match_dup 3)
2166         (and:GPR (match_dup 1)
2167                  (match_dup 2)))
2168    (set (match_dup 4)
2169         (clz:GPR (match_dup 3)))
2170    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2171                    (minus:GPR (match_dup 5)
2172                               (match_dup 4)))
2173               (clobber (reg:GPR CA_REGNO))])]
2174   ""
2176   if (TARGET_CTZ)
2177     {
2178       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2179       DONE;
2180     }
2182   operands[2] = gen_reg_rtx (<MODE>mode);
2183   operands[3] = gen_reg_rtx (<MODE>mode);
2184   operands[4] = gen_reg_rtx (<MODE>mode);
2185   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2188 (define_insn "ctz<mode>2_hw"
2189   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2190         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2191   "TARGET_CTZ"
2192   "cnttz<wd> %0,%1"
2193   [(set_attr "type" "cntlz")])
2195 (define_expand "ffs<mode>2"
2196   [(set (match_dup 2)
2197         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2198    (set (match_dup 3)
2199         (and:GPR (match_dup 1)
2200                  (match_dup 2)))
2201    (set (match_dup 4)
2202         (clz:GPR (match_dup 3)))
2203    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2204                    (minus:GPR (match_dup 5)
2205                               (match_dup 4)))
2206               (clobber (reg:GPR CA_REGNO))])]
2207   ""
2209   operands[2] = gen_reg_rtx (<MODE>mode);
2210   operands[3] = gen_reg_rtx (<MODE>mode);
2211   operands[4] = gen_reg_rtx (<MODE>mode);
2212   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2216 (define_expand "popcount<mode>2"
2217   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2218         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2219   "TARGET_POPCNTB || TARGET_POPCNTD"
2221   rs6000_emit_popcount (operands[0], operands[1]);
2222   DONE;
2225 (define_insn "popcntb<mode>2"
2226   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2227         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2228                     UNSPEC_POPCNTB))]
2229   "TARGET_POPCNTB"
2230   "popcntb %0,%1"
2231   [(set_attr "type" "popcnt")])
2233 (define_insn "popcntd<mode>2"
2234   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2235         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2236   "TARGET_POPCNTD"
2237   "popcnt<wd> %0,%1"
2238   [(set_attr "type" "popcnt")])
2241 (define_expand "parity<mode>2"
2242   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2243         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2244   "TARGET_POPCNTB"
2246   rs6000_emit_parity (operands[0], operands[1]);
2247   DONE;
2250 (define_insn "parity<mode>2_cmpb"
2251   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2252         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2253   "TARGET_CMPB && TARGET_POPCNTB"
2254   "prty<wd> %0,%1"
2255   [(set_attr "type" "popcnt")])
2258 ;; Since the hardware zeros the upper part of the register, save generating the
2259 ;; AND immediate if we are converting to unsigned
2260 (define_insn "*bswaphi2_extenddi"
2261   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2262         (zero_extend:DI
2263          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2264   "TARGET_POWERPC64"
2265   "lhbrx %0,%y1"
2266   [(set_attr "length" "4")
2267    (set_attr "type" "load")])
2269 (define_insn "*bswaphi2_extendsi"
2270   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2271         (zero_extend:SI
2272          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2273   ""
2274   "lhbrx %0,%y1"
2275   [(set_attr "length" "4")
2276    (set_attr "type" "load")])
2278 (define_expand "bswaphi2"
2279   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2280                    (bswap:HI
2281                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2282               (clobber (match_scratch:SI 2 ""))])]
2283   ""
2285   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2286     operands[1] = force_reg (HImode, operands[1]);
2289 (define_insn "bswaphi2_internal"
2290   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2291         (bswap:HI
2292          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2293    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2294   ""
2295   "@
2296    lhbrx %0,%y1
2297    sthbrx %1,%y0
2298    #"
2299   [(set_attr "length" "4,4,12")
2300    (set_attr "type" "load,store,*")])
2302 (define_split
2303   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2304         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2305    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2306   "reload_completed"
2307   [(set (match_dup 3)
2308         (and:SI (lshiftrt:SI (match_dup 4)
2309                              (const_int 8))
2310                 (const_int 255)))
2311    (set (match_dup 2)
2312         (and:SI (ashift:SI (match_dup 4)
2313                            (const_int 8))
2314                 (const_int 65280)))             ;; 0xff00
2315    (set (match_dup 3)
2316         (ior:SI (match_dup 3)
2317                 (match_dup 2)))]
2318   "
2320   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2321   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2324 (define_insn "*bswapsi2_extenddi"
2325   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2326         (zero_extend:DI
2327          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2328   "TARGET_POWERPC64"
2329   "lwbrx %0,%y1"
2330   [(set_attr "length" "4")
2331    (set_attr "type" "load")])
2333 (define_expand "bswapsi2"
2334   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2335         (bswap:SI
2336          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2337   ""
2339   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2340     operands[1] = force_reg (SImode, operands[1]);
2343 (define_insn "*bswapsi2_internal"
2344   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2345         (bswap:SI
2346          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2347   ""
2348   "@
2349    lwbrx %0,%y1
2350    stwbrx %1,%y0
2351    #"
2352   [(set_attr "length" "4,4,12")
2353    (set_attr "type" "load,store,*")])
2355 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2356 ;; zero_extract insns do not change for -mlittle.
2357 (define_split
2358   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2359         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2360   "reload_completed"
2361   [(set (match_dup 0)                                   ; DABC
2362         (rotate:SI (match_dup 1)
2363                    (const_int 24)))
2364    (set (match_dup 0)                                   ; DCBC
2365         (ior:SI (and:SI (ashift:SI (match_dup 1)
2366                                    (const_int 8))
2367                         (const_int 16711680))
2368                 (and:SI (match_dup 0)
2369                         (const_int -16711681))))
2370    (set (match_dup 0)                                   ; DCBA
2371         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2372                                      (const_int 24))
2373                         (const_int 255))
2374                 (and:SI (match_dup 0)
2375                         (const_int -256))))
2377   ]
2378   "")
2380 (define_expand "bswapdi2"
2381   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2382                    (bswap:DI
2383                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2384               (clobber (match_scratch:DI 2 ""))
2385               (clobber (match_scratch:DI 3 ""))])]
2386   ""
2388   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2389     operands[1] = force_reg (DImode, operands[1]);
2391   if (!TARGET_POWERPC64)
2392     {
2393       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2394          that uses 64-bit registers needs the same scratch registers as 64-bit
2395          mode.  */
2396       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2397       DONE;
2398     }
2401 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2402 (define_insn "*bswapdi2_ldbrx"
2403   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2404         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2405    (clobber (match_scratch:DI 2 "=X,X,&r"))
2406    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2407   "TARGET_POWERPC64 && TARGET_LDBRX
2408    && (REG_P (operands[0]) || REG_P (operands[1]))"
2409   "@
2410    ldbrx %0,%y1
2411    stdbrx %1,%y0
2412    #"
2413   [(set_attr "length" "4,4,36")
2414    (set_attr "type" "load,store,*")])
2416 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2417 (define_insn "*bswapdi2_64bit"
2418   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2419         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2420    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2421    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2422   "TARGET_POWERPC64 && !TARGET_LDBRX
2423    && (REG_P (operands[0]) || REG_P (operands[1]))
2424    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2425    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2426   "#"
2427   [(set_attr "length" "16,12,36")])
2429 (define_split
2430   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2431         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2432    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2433    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2434   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2435   [(const_int 0)]
2436   "
2438   rtx dest   = operands[0];
2439   rtx src    = operands[1];
2440   rtx op2    = operands[2];
2441   rtx op3    = operands[3];
2442   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2443                                     BYTES_BIG_ENDIAN ? 4 : 0);
2444   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2445                                      BYTES_BIG_ENDIAN ? 4 : 0);
2446   rtx addr1;
2447   rtx addr2;
2448   rtx word1;
2449   rtx word2;
2451   addr1 = XEXP (src, 0);
2452   if (GET_CODE (addr1) == PLUS)
2453     {
2454       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2455       if (TARGET_AVOID_XFORM)
2456         {
2457           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2458           addr2 = op2;
2459         }
2460       else
2461         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2462     }
2463   else if (TARGET_AVOID_XFORM)
2464     {
2465       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2466       addr2 = op2;
2467     }
2468   else
2469     {
2470       emit_move_insn (op2, GEN_INT (4));
2471       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2472     }
2474   word1 = change_address (src, SImode, addr1);
2475   word2 = change_address (src, SImode, addr2);
2477   if (BYTES_BIG_ENDIAN)
2478     {
2479       emit_insn (gen_bswapsi2 (op3_32, word2));
2480       emit_insn (gen_bswapsi2 (dest_32, word1));
2481     }
2482   else
2483     {
2484       emit_insn (gen_bswapsi2 (op3_32, word1));
2485       emit_insn (gen_bswapsi2 (dest_32, word2));
2486     }
2488   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2489   emit_insn (gen_iordi3 (dest, dest, op3));
2490   DONE;
2493 (define_split
2494   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2495         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2496    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2497    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2498   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2499   [(const_int 0)]
2500   "
2502   rtx dest   = operands[0];
2503   rtx src    = operands[1];
2504   rtx op2    = operands[2];
2505   rtx op3    = operands[3];
2506   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2507                                     BYTES_BIG_ENDIAN ? 4 : 0);
2508   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2509                                     BYTES_BIG_ENDIAN ? 4 : 0);
2510   rtx addr1;
2511   rtx addr2;
2512   rtx word1;
2513   rtx word2;
2515   addr1 = XEXP (dest, 0);
2516   if (GET_CODE (addr1) == PLUS)
2517     {
2518       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2519       if (TARGET_AVOID_XFORM)
2520         {
2521           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2522           addr2 = op2;
2523         }
2524       else
2525         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2526     }
2527   else if (TARGET_AVOID_XFORM)
2528     {
2529       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2530       addr2 = op2;
2531     }
2532   else
2533     {
2534       emit_move_insn (op2, GEN_INT (4));
2535       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2536     }
2538   word1 = change_address (dest, SImode, addr1);
2539   word2 = change_address (dest, SImode, addr2);
2541   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2543   if (BYTES_BIG_ENDIAN)
2544     {
2545       emit_insn (gen_bswapsi2 (word1, src_si));
2546       emit_insn (gen_bswapsi2 (word2, op3_si));
2547     }
2548   else
2549     {
2550       emit_insn (gen_bswapsi2 (word2, src_si));
2551       emit_insn (gen_bswapsi2 (word1, op3_si));
2552     }
2553   DONE;
2556 (define_split
2557   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2558         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2559    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2560    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2561   "TARGET_POWERPC64 && reload_completed"
2562   [(const_int 0)]
2563   "
2565   rtx dest    = operands[0];
2566   rtx src     = operands[1];
2567   rtx op2     = operands[2];
2568   rtx op3     = operands[3];
2569   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2570   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2571   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2572   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2573   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2575   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2576   emit_insn (gen_bswapsi2 (dest_si, src_si));
2577   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2578   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2579   emit_insn (gen_iordi3 (dest, dest, op3));
2580   DONE;
2583 (define_insn "bswapdi2_32bit"
2584   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2585         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2586    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2587   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2588   "#"
2589   [(set_attr "length" "16,12,36")])
2591 (define_split
2592   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2593         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2594    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2595   "!TARGET_POWERPC64 && reload_completed"
2596   [(const_int 0)]
2597   "
2599   rtx dest  = operands[0];
2600   rtx src   = operands[1];
2601   rtx op2   = operands[2];
2602   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2603   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2604   rtx addr1;
2605   rtx addr2;
2606   rtx word1;
2607   rtx word2;
2609   addr1 = XEXP (src, 0);
2610   if (GET_CODE (addr1) == PLUS)
2611     {
2612       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2613       if (TARGET_AVOID_XFORM
2614           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2615         {
2616           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2617           addr2 = op2;
2618         }
2619       else
2620         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2621     }
2622   else if (TARGET_AVOID_XFORM
2623            || REGNO (addr1) == REGNO (dest2))
2624     {
2625       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2626       addr2 = op2;
2627     }
2628   else
2629     {
2630       emit_move_insn (op2, GEN_INT (4));
2631       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2632     }
2634   word1 = change_address (src, SImode, addr1);
2635   word2 = change_address (src, SImode, addr2);
2637   emit_insn (gen_bswapsi2 (dest2, word1));
2638   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2639      thus allowing us to omit an early clobber on the output.  */
2640   emit_insn (gen_bswapsi2 (dest1, word2));
2641   DONE;
2644 (define_split
2645   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2646         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2647    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2648   "!TARGET_POWERPC64 && reload_completed"
2649   [(const_int 0)]
2650   "
2652   rtx dest = operands[0];
2653   rtx src  = operands[1];
2654   rtx op2  = operands[2];
2655   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2656   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2657   rtx addr1;
2658   rtx addr2;
2659   rtx word1;
2660   rtx word2;
2662   addr1 = XEXP (dest, 0);
2663   if (GET_CODE (addr1) == PLUS)
2664     {
2665       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2666       if (TARGET_AVOID_XFORM)
2667         {
2668           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2669           addr2 = op2;
2670         }
2671       else
2672         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2673     }
2674   else if (TARGET_AVOID_XFORM)
2675     {
2676       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2677       addr2 = op2;
2678     }
2679   else
2680     {
2681       emit_move_insn (op2, GEN_INT (4));
2682       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2683     }
2685   word1 = change_address (dest, SImode, addr1);
2686   word2 = change_address (dest, SImode, addr2);
2688   emit_insn (gen_bswapsi2 (word2, src1));
2689   emit_insn (gen_bswapsi2 (word1, src2));
2690   DONE;
2693 (define_split
2694   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2695         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2696    (clobber (match_operand:SI 2 "" ""))]
2697   "!TARGET_POWERPC64 && reload_completed"
2698   [(const_int 0)]
2699   "
2701   rtx dest  = operands[0];
2702   rtx src   = operands[1];
2703   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2704   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2705   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2706   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2708   emit_insn (gen_bswapsi2 (dest1, src2));
2709   emit_insn (gen_bswapsi2 (dest2, src1));
2710   DONE;
2714 (define_insn "mul<mode>3"
2715   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2716         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2717                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2718   ""
2719   "@
2720    mull<wd> %0,%1,%2
2721    mulli %0,%1,%2"
2722    [(set_attr "type" "mul")
2723     (set (attr "size")
2724       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2725                 (const_string "8")
2726              (match_operand:GPR 2 "short_cint_operand" "")
2727                 (const_string "16")]
2728         (const_string "<bits>")))])
2730 (define_insn_and_split "*mul<mode>3_dot"
2731   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2732         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2733                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2734                     (const_int 0)))
2735    (clobber (match_scratch:GPR 0 "=r,r"))]
2736   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2737   "@
2738    mull<wd>. %0,%1,%2
2739    #"
2740   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2741   [(set (match_dup 0)
2742         (mult:GPR (match_dup 1)
2743                   (match_dup 2)))
2744    (set (match_dup 3)
2745         (compare:CC (match_dup 0)
2746                     (const_int 0)))]
2747   ""
2748   [(set_attr "type" "mul")
2749    (set_attr "size" "<bits>")
2750    (set_attr "dot" "yes")
2751    (set_attr "length" "4,8")])
2753 (define_insn_and_split "*mul<mode>3_dot2"
2754   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2755         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2756                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2757                     (const_int 0)))
2758    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2759         (mult:GPR (match_dup 1)
2760                   (match_dup 2)))]
2761   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2762   "@
2763    mull<wd>. %0,%1,%2
2764    #"
2765   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2766   [(set (match_dup 0)
2767         (mult:GPR (match_dup 1)
2768                   (match_dup 2)))
2769    (set (match_dup 3)
2770         (compare:CC (match_dup 0)
2771                     (const_int 0)))]
2772   ""
2773   [(set_attr "type" "mul")
2774    (set_attr "size" "<bits>")
2775    (set_attr "dot" "yes")
2776    (set_attr "length" "4,8")])
2779 (define_expand "<su>mul<mode>3_highpart"
2780   [(set (match_operand:GPR 0 "gpc_reg_operand")
2781         (subreg:GPR
2782           (mult:<DMODE> (any_extend:<DMODE>
2783                           (match_operand:GPR 1 "gpc_reg_operand"))
2784                         (any_extend:<DMODE>
2785                           (match_operand:GPR 2 "gpc_reg_operand")))
2786          0))]
2787   ""
2789   if (<MODE>mode == SImode && TARGET_POWERPC64)
2790     {
2791       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2792                                              operands[2]));
2793       DONE;
2794     }
2796   if (!WORDS_BIG_ENDIAN)
2797     {
2798       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2799                                                  operands[2]));
2800       DONE;
2801     }
2804 (define_insn "*<su>mul<mode>3_highpart"
2805   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2806         (subreg:GPR
2807           (mult:<DMODE> (any_extend:<DMODE>
2808                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2809                         (any_extend:<DMODE>
2810                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2811          0))]
2812   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2813   "mulh<wd><u> %0,%1,%2"
2814   [(set_attr "type" "mul")
2815    (set_attr "size" "<bits>")])
2817 (define_insn "<su>mulsi3_highpart_le"
2818   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2819         (subreg:SI
2820           (mult:DI (any_extend:DI
2821                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2822                    (any_extend:DI
2823                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2824          4))]
2825   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2826   "mulhw<u> %0,%1,%2"
2827   [(set_attr "type" "mul")])
2829 (define_insn "<su>muldi3_highpart_le"
2830   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2831         (subreg:DI
2832           (mult:TI (any_extend:TI
2833                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2834                    (any_extend:TI
2835                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2836          8))]
2837   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2838   "mulhd<u> %0,%1,%2"
2839   [(set_attr "type" "mul")
2840    (set_attr "size" "64")])
2842 (define_insn "<su>mulsi3_highpart_64"
2843   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2844         (truncate:SI
2845           (lshiftrt:DI
2846             (mult:DI (any_extend:DI
2847                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2848                      (any_extend:DI
2849                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2850             (const_int 32))))]
2851   "TARGET_POWERPC64"
2852   "mulhw<u> %0,%1,%2"
2853   [(set_attr "type" "mul")])
2855 (define_expand "<u>mul<mode><dmode>3"
2856   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2857         (mult:<DMODE> (any_extend:<DMODE>
2858                         (match_operand:GPR 1 "gpc_reg_operand"))
2859                       (any_extend:<DMODE>
2860                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2861   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2863   rtx l = gen_reg_rtx (<MODE>mode);
2864   rtx h = gen_reg_rtx (<MODE>mode);
2865   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2866   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2867   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2868   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2869   DONE;
2872 (define_insn "*maddld4"
2873   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2874         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2875                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2876                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2877   "TARGET_MADDLD"
2878   "maddld %0,%1,%2,%3"
2879   [(set_attr "type" "mul")])
2881 (define_insn "udiv<mode>3"
2882   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2883         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2884                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2885   ""
2886   "div<wd>u %0,%1,%2"
2887   [(set_attr "type" "div")
2888    (set_attr "size" "<bits>")])
2891 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2892 ;; modulus.  If it isn't a power of two, force operands into register and do
2893 ;; a normal divide.
2894 (define_expand "div<mode>3"
2895   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2896         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2897                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2898   ""
2900   if (CONST_INT_P (operands[2])
2901       && INTVAL (operands[2]) > 0
2902       && exact_log2 (INTVAL (operands[2])) >= 0)
2903     {
2904       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2905       DONE;
2906     }
2908   operands[2] = force_reg (<MODE>mode, operands[2]);
2911 (define_insn "*div<mode>3"
2912   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2913         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2914                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2915   ""
2916   "div<wd> %0,%1,%2"
2917   [(set_attr "type" "div")
2918    (set_attr "size" "<bits>")])
2920 (define_insn "div<mode>3_sra"
2921   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2922         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2923                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2924    (clobber (reg:GPR CA_REGNO))]
2925   ""
2926   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2927   [(set_attr "type" "two")
2928    (set_attr "length" "8")])
2930 (define_insn_and_split "*div<mode>3_sra_dot"
2931   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2932         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2933                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2934                     (const_int 0)))
2935    (clobber (match_scratch:GPR 0 "=r,r"))
2936    (clobber (reg:GPR CA_REGNO))]
2937   "<MODE>mode == Pmode"
2938   "@
2939    sra<wd>i %0,%1,%p2\;addze. %0,%0
2940    #"
2941   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2942   [(parallel [(set (match_dup 0)
2943                    (div:GPR (match_dup 1)
2944                             (match_dup 2)))
2945               (clobber (reg:GPR CA_REGNO))])
2946    (set (match_dup 3)
2947         (compare:CC (match_dup 0)
2948                     (const_int 0)))]
2949   ""
2950   [(set_attr "type" "two")
2951    (set_attr "length" "8,12")
2952    (set_attr "cell_micro" "not")])
2954 (define_insn_and_split "*div<mode>3_sra_dot2"
2955   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2956         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2957                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2958                     (const_int 0)))
2959    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2960         (div:GPR (match_dup 1)
2961                  (match_dup 2)))
2962    (clobber (reg:GPR CA_REGNO))]
2963   "<MODE>mode == Pmode"
2964   "@
2965    sra<wd>i %0,%1,%p2\;addze. %0,%0
2966    #"
2967   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2968   [(parallel [(set (match_dup 0)
2969                    (div:GPR (match_dup 1)
2970                             (match_dup 2)))
2971               (clobber (reg:GPR CA_REGNO))])
2972    (set (match_dup 3)
2973         (compare:CC (match_dup 0)
2974                     (const_int 0)))]
2975   ""
2976   [(set_attr "type" "two")
2977    (set_attr "length" "8,12")
2978    (set_attr "cell_micro" "not")])
2980 (define_expand "mod<mode>3"
2981   [(set (match_operand:GPR 0 "gpc_reg_operand")
2982         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
2983                  (match_operand:GPR 2 "reg_or_cint_operand")))]
2984   ""
2986   int i;
2987   rtx temp1;
2988   rtx temp2;
2990   if (GET_CODE (operands[2]) != CONST_INT
2991       || INTVAL (operands[2]) <= 0
2992       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2993     {
2994       if (!TARGET_MODULO)
2995         FAIL;
2997       operands[2] = force_reg (<MODE>mode, operands[2]);
2998     }
2999   else
3000     {
3001       temp1 = gen_reg_rtx (<MODE>mode);
3002       temp2 = gen_reg_rtx (<MODE>mode);
3004       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3005       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3006       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3007       DONE;
3008     }
3011 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3012 ;; mod, prefer putting the result of mod into a different register
3013 (define_insn "*mod<mode>3"
3014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3015         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3016                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3017   "TARGET_MODULO"
3018   "mods<wd> %0,%1,%2"
3019   [(set_attr "type" "div")
3020    (set_attr "size" "<bits>")])
3023 (define_insn "umod<mode>3"
3024   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3025         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3026                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3027   "TARGET_MODULO"
3028   "modu<wd> %0,%1,%2"
3029   [(set_attr "type" "div")
3030    (set_attr "size" "<bits>")])
3032 ;; On machines with modulo support, do a combined div/mod the old fashioned
3033 ;; method, since the multiply/subtract is faster than doing the mod instruction
3034 ;; after a divide.
3036 (define_peephole2
3037   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3038         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3039                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3040    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3041         (mod:GPR (match_dup 1)
3042                  (match_dup 2)))]
3043   "TARGET_MODULO
3044    && ! reg_mentioned_p (operands[0], operands[1])
3045    && ! reg_mentioned_p (operands[0], operands[2])
3046    && ! reg_mentioned_p (operands[3], operands[1])
3047    && ! reg_mentioned_p (operands[3], operands[2])"
3048   [(set (match_dup 0)
3049         (div:GPR (match_dup 1)
3050                  (match_dup 2)))
3051    (set (match_dup 3)
3052         (mult:GPR (match_dup 0)
3053                   (match_dup 2)))
3054    (set (match_dup 3)
3055         (minus:GPR (match_dup 1)
3056                    (match_dup 3)))])
3058 (define_peephole2
3059   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3060         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3061                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3062    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3063         (umod:GPR (match_dup 1)
3064                   (match_dup 2)))]
3065   "TARGET_MODULO
3066    && ! reg_mentioned_p (operands[0], operands[1])
3067    && ! reg_mentioned_p (operands[0], operands[2])
3068    && ! reg_mentioned_p (operands[3], operands[1])
3069    && ! reg_mentioned_p (operands[3], operands[2])"
3070   [(set (match_dup 0)
3071         (div:GPR (match_dup 1)
3072                  (match_dup 2)))
3073    (set (match_dup 3)
3074         (mult:GPR (match_dup 0)
3075                   (match_dup 2)))
3076    (set (match_dup 3)
3077         (minus:GPR (match_dup 1)
3078                    (match_dup 3)))])
3081 ;; Logical instructions
3082 ;; The logical instructions are mostly combined by using match_operator,
3083 ;; but the plain AND insns are somewhat different because there is no
3084 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3085 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3087 (define_expand "and<mode>3"
3088   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3089         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3090                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3091   ""
3093   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3094     {
3095       rs6000_split_logical (operands, AND, false, false, false);
3096       DONE;
3097     }
3099   if (CONST_INT_P (operands[2]))
3100     {
3101       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3102         {
3103           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3104           DONE;
3105         }
3107       if (logical_const_operand (operands[2], <MODE>mode)
3108           && rs6000_gen_cell_microcode)
3109         {
3110           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3111           DONE;
3112         }
3114       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3115         {
3116           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3117           DONE;
3118         }
3120       operands[2] = force_reg (<MODE>mode, operands[2]);
3121     }
3125 (define_insn "and<mode>3_imm"
3126   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3127         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3128                  (match_operand:GPR 2 "logical_const_operand" "n")))
3129    (clobber (match_scratch:CC 3 "=x"))]
3130   "rs6000_gen_cell_microcode
3131    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3132   "andi%e2. %0,%1,%u2"
3133   [(set_attr "type" "logical")
3134    (set_attr "dot" "yes")])
3136 (define_insn_and_split "*and<mode>3_imm_dot"
3137   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3138         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3139                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3140                     (const_int 0)))
3141    (clobber (match_scratch:GPR 0 "=r,r"))
3142    (clobber (match_scratch:CC 4 "=X,x"))]
3143   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3144    && rs6000_gen_cell_microcode
3145    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3146   "@
3147    andi%e2. %0,%1,%u2
3148    #"
3149   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3150   [(parallel [(set (match_dup 0)
3151                    (and:GPR (match_dup 1)
3152                             (match_dup 2)))
3153               (clobber (match_dup 4))])
3154    (set (match_dup 3)
3155         (compare:CC (match_dup 0)
3156                     (const_int 0)))]
3157   ""
3158   [(set_attr "type" "logical")
3159    (set_attr "dot" "yes")
3160    (set_attr "length" "4,8")])
3162 (define_insn_and_split "*and<mode>3_imm_dot2"
3163   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3164         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3165                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3166                     (const_int 0)))
3167    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3168         (and:GPR (match_dup 1)
3169                  (match_dup 2)))
3170    (clobber (match_scratch:CC 4 "=X,x"))]
3171   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3172    && rs6000_gen_cell_microcode
3173    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3174   "@
3175    andi%e2. %0,%1,%u2
3176    #"
3177   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3178   [(parallel [(set (match_dup 0)
3179                    (and:GPR (match_dup 1)
3180                             (match_dup 2)))
3181               (clobber (match_dup 4))])
3182    (set (match_dup 3)
3183         (compare:CC (match_dup 0)
3184                     (const_int 0)))]
3185   ""
3186   [(set_attr "type" "logical")
3187    (set_attr "dot" "yes")
3188    (set_attr "length" "4,8")])
3190 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3191   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3192         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3193                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3194                     (const_int 0)))
3195    (clobber (match_scratch:GPR 0 "=r,r"))]
3196   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3197    && rs6000_gen_cell_microcode"
3198   "@
3199    andi%e2. %0,%1,%u2
3200    #"
3201   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3202   [(set (match_dup 0)
3203         (and:GPR (match_dup 1)
3204                  (match_dup 2)))
3205    (set (match_dup 3)
3206         (compare:CC (match_dup 0)
3207                     (const_int 0)))]
3208   ""
3209   [(set_attr "type" "logical")
3210    (set_attr "dot" "yes")
3211    (set_attr "length" "4,8")])
3213 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3214   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3215         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3216                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3217                     (const_int 0)))
3218    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3219         (and:GPR (match_dup 1)
3220                  (match_dup 2)))]
3221   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3222    && rs6000_gen_cell_microcode"
3223   "@
3224    andi%e2. %0,%1,%u2
3225    #"
3226   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3227   [(set (match_dup 0)
3228         (and:GPR (match_dup 1)
3229                  (match_dup 2)))
3230    (set (match_dup 3)
3231         (compare:CC (match_dup 0)
3232                     (const_int 0)))]
3233   ""
3234   [(set_attr "type" "logical")
3235    (set_attr "dot" "yes")
3236    (set_attr "length" "4,8")])
3238 (define_insn "*and<mode>3_imm_dot_shifted"
3239   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3240         (compare:CC
3241           (and:GPR
3242             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3243                           (match_operand:SI 4 "const_int_operand" "n"))
3244             (match_operand:GPR 2 "const_int_operand" "n"))
3245           (const_int 0)))
3246    (clobber (match_scratch:GPR 0 "=r"))]
3247   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3248                                    << INTVAL (operands[4])),
3249                           DImode)
3250    && (<MODE>mode == Pmode
3251        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3252    && rs6000_gen_cell_microcode"
3254   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3255   return "andi%e2. %0,%1,%u2";
3257   [(set_attr "type" "logical")
3258    (set_attr "dot" "yes")])
3261 (define_insn "and<mode>3_mask"
3262   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3263         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3264                  (match_operand:GPR 2 "const_int_operand" "n")))]
3265   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3267   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3269   [(set_attr "type" "shift")])
3271 (define_insn_and_split "*and<mode>3_mask_dot"
3272   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3273         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3274                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3275                     (const_int 0)))
3276    (clobber (match_scratch:GPR 0 "=r,r"))]
3277   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3278    && rs6000_gen_cell_microcode
3279    && !logical_const_operand (operands[2], <MODE>mode)
3280    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3282   if (which_alternative == 0)
3283     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3284   else
3285     return "#";
3287   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3288   [(set (match_dup 0)
3289         (and:GPR (match_dup 1)
3290                  (match_dup 2)))
3291    (set (match_dup 3)
3292         (compare:CC (match_dup 0)
3293                     (const_int 0)))]
3294   ""
3295   [(set_attr "type" "shift")
3296    (set_attr "dot" "yes")
3297    (set_attr "length" "4,8")])
3299 (define_insn_and_split "*and<mode>3_mask_dot2"
3300   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3301         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3302                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3303                     (const_int 0)))
3304    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3305         (and:GPR (match_dup 1)
3306                  (match_dup 2)))]
3307   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3308    && rs6000_gen_cell_microcode
3309    && !logical_const_operand (operands[2], <MODE>mode)
3310    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3312   if (which_alternative == 0)
3313     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3314   else
3315     return "#";
3317   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3318   [(set (match_dup 0)
3319         (and:GPR (match_dup 1)
3320                  (match_dup 2)))
3321    (set (match_dup 3)
3322         (compare:CC (match_dup 0)
3323                     (const_int 0)))]
3324   ""
3325   [(set_attr "type" "shift")
3326    (set_attr "dot" "yes")
3327    (set_attr "length" "4,8")])
3330 (define_insn_and_split "*and<mode>3_2insn"
3331   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3332         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3333                  (match_operand:GPR 2 "const_int_operand" "n")))]
3334   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3335    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3336         || (logical_const_operand (operands[2], <MODE>mode)
3337             && rs6000_gen_cell_microcode))"
3338   "#"
3339   "&& 1"
3340   [(pc)]
3342   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3343   DONE;
3345   [(set_attr "type" "shift")
3346    (set_attr "length" "8")])
3348 (define_insn_and_split "*and<mode>3_2insn_dot"
3349   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3350         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3351                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3352                     (const_int 0)))
3353    (clobber (match_scratch:GPR 0 "=r,r"))]
3354   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3355    && rs6000_gen_cell_microcode
3356    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3357    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3358         || (logical_const_operand (operands[2], <MODE>mode)
3359             && rs6000_gen_cell_microcode))"
3360   "#"
3361   "&& reload_completed"
3362   [(pc)]
3364   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3365   DONE;
3367   [(set_attr "type" "shift")
3368    (set_attr "dot" "yes")
3369    (set_attr "length" "8,12")])
3371 (define_insn_and_split "*and<mode>3_2insn_dot2"
3372   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3373         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3374                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3375                     (const_int 0)))
3376    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3377         (and:GPR (match_dup 1)
3378                  (match_dup 2)))]
3379   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3380    && rs6000_gen_cell_microcode
3381    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3382    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3383         || (logical_const_operand (operands[2], <MODE>mode)
3384             && rs6000_gen_cell_microcode))"
3385   "#"
3386   "&& reload_completed"
3387   [(pc)]
3389   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3390   DONE;
3392   [(set_attr "type" "shift")
3393    (set_attr "dot" "yes")
3394    (set_attr "length" "8,12")])
3397 (define_expand "<code><mode>3"
3398   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3399         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3400                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3401   ""
3403   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3404     {
3405       rs6000_split_logical (operands, <CODE>, false, false, false);
3406       DONE;
3407     }
3409   if (non_logical_cint_operand (operands[2], <MODE>mode))
3410     {
3411       rtx tmp = ((!can_create_pseudo_p ()
3412                   || rtx_equal_p (operands[0], operands[1]))
3413                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3415       HOST_WIDE_INT value = INTVAL (operands[2]);
3416       HOST_WIDE_INT lo = value & 0xffff;
3417       HOST_WIDE_INT hi = value - lo;
3419       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3420       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3421       DONE;
3422     }
3424   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3425     operands[2] = force_reg (<MODE>mode, operands[2]);
3428 (define_split
3429   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3430         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3431                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3432   ""
3433   [(set (match_dup 3)
3434         (iorxor:GPR (match_dup 1)
3435                     (match_dup 4)))
3436    (set (match_dup 0)
3437         (iorxor:GPR (match_dup 3)
3438                     (match_dup 5)))]
3440   operands[3] = ((!can_create_pseudo_p ()
3441                   || rtx_equal_p (operands[0], operands[1]))
3442                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3444   HOST_WIDE_INT value = INTVAL (operands[2]);
3445   HOST_WIDE_INT lo = value & 0xffff;
3446   HOST_WIDE_INT hi = value - lo;
3448   operands[4] = GEN_INT (hi);
3449   operands[5] = GEN_INT (lo);
3452 (define_insn "*bool<mode>3_imm"
3453   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3454         (match_operator:GPR 3 "boolean_or_operator"
3455          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3456           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3457   ""
3458   "%q3i%e2 %0,%1,%u2"
3459   [(set_attr "type" "logical")])
3461 (define_insn "*bool<mode>3"
3462   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3463         (match_operator:GPR 3 "boolean_operator"
3464          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3465           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3466   ""
3467   "%q3 %0,%1,%2"
3468   [(set_attr "type" "logical")])
3470 (define_insn_and_split "*bool<mode>3_dot"
3471   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3472         (compare:CC (match_operator:GPR 3 "boolean_operator"
3473          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3474           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3475          (const_int 0)))
3476    (clobber (match_scratch:GPR 0 "=r,r"))]
3477   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3478   "@
3479    %q3. %0,%1,%2
3480    #"
3481   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3482   [(set (match_dup 0)
3483         (match_dup 3))
3484    (set (match_dup 4)
3485         (compare:CC (match_dup 0)
3486                     (const_int 0)))]
3487   ""
3488   [(set_attr "type" "logical")
3489    (set_attr "dot" "yes")
3490    (set_attr "length" "4,8")])
3492 (define_insn_and_split "*bool<mode>3_dot2"
3493   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3494         (compare:CC (match_operator:GPR 3 "boolean_operator"
3495          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3496           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3497          (const_int 0)))
3498    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3499         (match_dup 3))]
3500   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3501   "@
3502    %q3. %0,%1,%2
3503    #"
3504   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3505   [(set (match_dup 0)
3506         (match_dup 3))
3507    (set (match_dup 4)
3508         (compare:CC (match_dup 0)
3509                     (const_int 0)))]
3510   ""
3511   [(set_attr "type" "logical")
3512    (set_attr "dot" "yes")
3513    (set_attr "length" "4,8")])
3516 (define_insn "*boolc<mode>3"
3517   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3518         (match_operator:GPR 3 "boolean_operator"
3519          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3520           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3521   ""
3522   "%q3 %0,%1,%2"
3523   [(set_attr "type" "logical")])
3525 (define_insn_and_split "*boolc<mode>3_dot"
3526   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3527         (compare:CC (match_operator:GPR 3 "boolean_operator"
3528          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3529           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3530          (const_int 0)))
3531    (clobber (match_scratch:GPR 0 "=r,r"))]
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")])
3547 (define_insn_and_split "*boolc<mode>3_dot2"
3548   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3549         (compare:CC (match_operator:GPR 3 "boolean_operator"
3550          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3551           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3552          (const_int 0)))
3553    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3554         (match_dup 3))]
3555   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3556   "@
3557    %q3. %0,%1,%2
3558    #"
3559   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3560   [(set (match_dup 0)
3561         (match_dup 3))
3562    (set (match_dup 4)
3563         (compare:CC (match_dup 0)
3564                     (const_int 0)))]
3565   ""
3566   [(set_attr "type" "logical")
3567    (set_attr "dot" "yes")
3568    (set_attr "length" "4,8")])
3571 (define_insn "*boolcc<mode>3"
3572   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3573         (match_operator:GPR 3 "boolean_operator"
3574          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3575           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3576   ""
3577   "%q3 %0,%1,%2"
3578   [(set_attr "type" "logical")])
3580 (define_insn_and_split "*boolcc<mode>3_dot"
3581   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3582         (compare:CC (match_operator:GPR 3 "boolean_operator"
3583          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3584           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3585          (const_int 0)))
3586    (clobber (match_scratch:GPR 0 "=r,r"))]
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")])
3602 (define_insn_and_split "*boolcc<mode>3_dot2"
3603   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3604         (compare:CC (match_operator:GPR 3 "boolean_operator"
3605          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3606           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3607          (const_int 0)))
3608    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3609         (match_dup 3))]
3610   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3611   "@
3612    %q3. %0,%1,%2
3613    #"
3614   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3615   [(set (match_dup 0)
3616         (match_dup 3))
3617    (set (match_dup 4)
3618         (compare:CC (match_dup 0)
3619                     (const_int 0)))]
3620   ""
3621   [(set_attr "type" "logical")
3622    (set_attr "dot" "yes")
3623    (set_attr "length" "4,8")])
3626 ;; TODO: Should have dots of this as well.
3627 (define_insn "*eqv<mode>3"
3628   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3629         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3630                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3631   ""
3632   "eqv %0,%1,%2"
3633   [(set_attr "type" "logical")])
3635 ;; Rotate-and-mask and insert.
3637 (define_insn "*rotl<mode>3_mask"
3638   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3639         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3640                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3641                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3642                  (match_operand:GPR 3 "const_int_operand" "n")))]
3643   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3645   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3647   [(set_attr "type" "shift")
3648    (set_attr "maybe_var_shift" "yes")])
3650 (define_insn_and_split "*rotl<mode>3_mask_dot"
3651   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3652         (compare:CC
3653           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3654                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3655                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3656                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3657           (const_int 0)))
3658    (clobber (match_scratch:GPR 0 "=r,r"))]
3659   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3660    && rs6000_gen_cell_microcode
3661    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3663   if (which_alternative == 0)
3664     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3665   else
3666     return "#";
3668   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3669   [(set (match_dup 0)
3670         (and:GPR (match_dup 4)
3671                  (match_dup 3)))
3672    (set (match_dup 5)
3673         (compare:CC (match_dup 0)
3674                     (const_int 0)))]
3675   ""
3676   [(set_attr "type" "shift")
3677    (set_attr "maybe_var_shift" "yes")
3678    (set_attr "dot" "yes")
3679    (set_attr "length" "4,8")])
3681 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3682   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3683         (compare:CC
3684           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3685                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3686                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3687                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3688           (const_int 0)))
3689    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3690         (and:GPR (match_dup 4)
3691                  (match_dup 3)))]
3692   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3693    && rs6000_gen_cell_microcode
3694    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3696   if (which_alternative == 0)
3697     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3698   else
3699     return "#";
3701   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3702   [(set (match_dup 0)
3703         (and:GPR (match_dup 4)
3704                  (match_dup 3)))
3705    (set (match_dup 5)
3706         (compare:CC (match_dup 0)
3707                     (const_int 0)))]
3708   ""
3709   [(set_attr "type" "shift")
3710    (set_attr "maybe_var_shift" "yes")
3711    (set_attr "dot" "yes")
3712    (set_attr "length" "4,8")])
3714 ; Special case for less-than-0.  We can do it with just one machine
3715 ; instruction, but the generic optimizers do not realise it is cheap.
3716 (define_insn "*lt0_disi"
3717   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3718         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3719                (const_int 0)))]
3720   "TARGET_POWERPC64"
3721   "rlwinm %0,%1,1,31,31"
3722   [(set_attr "type" "shift")])
3726 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3727 ; both are an AND so are the same precedence).
3728 (define_insn "*rotl<mode>3_insert"
3729   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3730         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3731                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3732                             (match_operand:SI 2 "const_int_operand" "n")])
3733                           (match_operand:GPR 3 "const_int_operand" "n"))
3734                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3735                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3736   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3737    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3739   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3741   [(set_attr "type" "insert")])
3742 ; FIXME: this needs an attr "size", so that the scheduler can see the
3743 ; difference between rlwimi and rldimi.  We also might want dot forms,
3744 ; but not for rlwimi on POWER4 and similar processors.
3746 (define_insn "*rotl<mode>3_insert_2"
3747   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3748         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3749                           (match_operand:GPR 6 "const_int_operand" "n"))
3750                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3751                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3752                             (match_operand:SI 2 "const_int_operand" "n")])
3753                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3754   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3755    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3757   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3759   [(set_attr "type" "insert")])
3761 ; There are also some forms without one of the ANDs.
3762 (define_insn "*rotl<mode>3_insert_3"
3763   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3764         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3765                           (match_operand:GPR 4 "const_int_operand" "n"))
3766                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3767                              (match_operand:SI 2 "const_int_operand" "n"))))]
3768   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3770   if (<MODE>mode == SImode)
3771     return "rlwimi %0,%1,%h2,0,31-%h2";
3772   else
3773     return "rldimi %0,%1,%H2,0";
3775   [(set_attr "type" "insert")])
3777 (define_insn "*rotl<mode>3_insert_4"
3778   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3779         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3780                           (match_operand:GPR 4 "const_int_operand" "n"))
3781                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3782                                (match_operand:SI 2 "const_int_operand" "n"))))]
3783   "<MODE>mode == SImode &&
3784    GET_MODE_PRECISION (<MODE>mode)
3785    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3787   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3788                          - INTVAL (operands[2]));
3789   if (<MODE>mode == SImode)
3790     return "rlwimi %0,%1,%h2,32-%h2,31";
3791   else
3792     return "rldimi %0,%1,%H2,64-%H2";
3794   [(set_attr "type" "insert")])
3797 ; This handles the important case of multiple-precision shifts.  There is
3798 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3799 (define_split
3800   [(set (match_operand:GPR 0 "gpc_reg_operand")
3801         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3802                              (match_operand:SI 3 "const_int_operand"))
3803                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3804                                (match_operand:SI 4 "const_int_operand"))))]
3805   "can_create_pseudo_p ()
3806    && INTVAL (operands[3]) + INTVAL (operands[4])
3807       >= GET_MODE_PRECISION (<MODE>mode)"
3808   [(set (match_dup 5)
3809         (lshiftrt:GPR (match_dup 2)
3810                       (match_dup 4)))
3811    (set (match_dup 0)
3812         (ior:GPR (and:GPR (match_dup 5)
3813                           (match_dup 6))
3814                  (ashift:GPR (match_dup 1)
3815                              (match_dup 3))))]
3817   unsigned HOST_WIDE_INT mask = 1;
3818   mask = (mask << INTVAL (operands[3])) - 1;
3819   operands[5] = gen_reg_rtx (<MODE>mode);
3820   operands[6] = GEN_INT (mask);
3823 (define_split
3824   [(set (match_operand:GPR 0 "gpc_reg_operand")
3825         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3826                                (match_operand:SI 4 "const_int_operand"))
3827                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3828                              (match_operand:SI 3 "const_int_operand"))))]
3829   "can_create_pseudo_p ()
3830    && INTVAL (operands[3]) + INTVAL (operands[4])
3831       >= GET_MODE_PRECISION (<MODE>mode)"
3832   [(set (match_dup 5)
3833         (lshiftrt:GPR (match_dup 2)
3834                       (match_dup 4)))
3835    (set (match_dup 0)
3836         (ior:GPR (and:GPR (match_dup 5)
3837                           (match_dup 6))
3838                  (ashift:GPR (match_dup 1)
3839                              (match_dup 3))))]
3841   unsigned HOST_WIDE_INT mask = 1;
3842   mask = (mask << INTVAL (operands[3])) - 1;
3843   operands[5] = gen_reg_rtx (<MODE>mode);
3844   operands[6] = GEN_INT (mask);
3848 ; Another important case is setting some bits to 1; we can do that with
3849 ; an insert instruction, in many cases.
3850 (define_insn_and_split "*ior<mode>_mask"
3851   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3852         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3853                  (match_operand:GPR 2 "const_int_operand" "n")))
3854    (clobber (match_scratch:GPR 3 "=r"))]
3855   "!logical_const_operand (operands[2], <MODE>mode)
3856    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3857   "#"
3858   "&& 1"
3859   [(set (match_dup 3)
3860         (const_int -1))
3861    (set (match_dup 0)
3862         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3863                                       (match_dup 4))
3864                           (match_dup 2))
3865                  (and:GPR (match_dup 1)
3866                           (match_dup 5))))]
3868   int nb, ne;
3869   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3870   if (GET_CODE (operands[3]) == SCRATCH)
3871     operands[3] = gen_reg_rtx (<MODE>mode);
3872   operands[4] = GEN_INT (ne);
3873   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3875   [(set_attr "type" "two")
3876    (set_attr "length" "8")])
3879 ;; Now the simple shifts.
3881 (define_insn "rotl<mode>3"
3882   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3883         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3884                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3885   ""
3886   "rotl<wd>%I2 %0,%1,%<hH>2"
3887   [(set_attr "type" "shift")
3888    (set_attr "maybe_var_shift" "yes")])
3890 (define_insn "*rotlsi3_64"
3891   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3892         (zero_extend:DI
3893             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3894                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3895   "TARGET_POWERPC64"
3896   "rotlw%I2 %0,%1,%h2"
3897   [(set_attr "type" "shift")
3898    (set_attr "maybe_var_shift" "yes")])
3900 (define_insn_and_split "*rotl<mode>3_dot"
3901   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3902         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3903                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3904                     (const_int 0)))
3905    (clobber (match_scratch:GPR 0 "=r,r"))]
3906   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3907   "@
3908    rotl<wd>%I2. %0,%1,%<hH>2
3909    #"
3910   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3911   [(set (match_dup 0)
3912         (rotate:GPR (match_dup 1)
3913                     (match_dup 2)))
3914    (set (match_dup 3)
3915         (compare:CC (match_dup 0)
3916                     (const_int 0)))]
3917   ""
3918   [(set_attr "type" "shift")
3919    (set_attr "maybe_var_shift" "yes")
3920    (set_attr "dot" "yes")
3921    (set_attr "length" "4,8")])
3923 (define_insn_and_split "*rotl<mode>3_dot2"
3924   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3925         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3926                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3927                     (const_int 0)))
3928    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3929         (rotate:GPR (match_dup 1)
3930                     (match_dup 2)))]
3931   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3932   "@
3933    rotl<wd>%I2. %0,%1,%<hH>2
3934    #"
3935   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3936   [(set (match_dup 0)
3937         (rotate:GPR (match_dup 1)
3938                     (match_dup 2)))
3939    (set (match_dup 3)
3940         (compare:CC (match_dup 0)
3941                     (const_int 0)))]
3942   ""
3943   [(set_attr "type" "shift")
3944    (set_attr "maybe_var_shift" "yes")
3945    (set_attr "dot" "yes")
3946    (set_attr "length" "4,8")])
3949 (define_insn "ashl<mode>3"
3950   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3951         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3952                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3953   ""
3954   "sl<wd>%I2 %0,%1,%<hH>2"
3955   [(set_attr "type" "shift")
3956    (set_attr "maybe_var_shift" "yes")])
3958 (define_insn "*ashlsi3_64"
3959   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3960         (zero_extend:DI
3961             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3962                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3963   "TARGET_POWERPC64"
3964   "slw%I2 %0,%1,%h2"
3965   [(set_attr "type" "shift")
3966    (set_attr "maybe_var_shift" "yes")])
3968 (define_insn_and_split "*ashl<mode>3_dot"
3969   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3970         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3971                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3972                     (const_int 0)))
3973    (clobber (match_scratch:GPR 0 "=r,r"))]
3974   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3975   "@
3976    sl<wd>%I2. %0,%1,%<hH>2
3977    #"
3978   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3979   [(set (match_dup 0)
3980         (ashift:GPR (match_dup 1)
3981                     (match_dup 2)))
3982    (set (match_dup 3)
3983         (compare:CC (match_dup 0)
3984                     (const_int 0)))]
3985   ""
3986   [(set_attr "type" "shift")
3987    (set_attr "maybe_var_shift" "yes")
3988    (set_attr "dot" "yes")
3989    (set_attr "length" "4,8")])
3991 (define_insn_and_split "*ashl<mode>3_dot2"
3992   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3993         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3994                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3995                     (const_int 0)))
3996    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3997         (ashift:GPR (match_dup 1)
3998                     (match_dup 2)))]
3999   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4000   "@
4001    sl<wd>%I2. %0,%1,%<hH>2
4002    #"
4003   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4004   [(set (match_dup 0)
4005         (ashift:GPR (match_dup 1)
4006                     (match_dup 2)))
4007    (set (match_dup 3)
4008         (compare:CC (match_dup 0)
4009                     (const_int 0)))]
4010   ""
4011   [(set_attr "type" "shift")
4012    (set_attr "maybe_var_shift" "yes")
4013    (set_attr "dot" "yes")
4014    (set_attr "length" "4,8")])
4016 ;; Pretend we have a memory form of extswsli until register allocation is done
4017 ;; so that we use LWZ to load the value from memory, instead of LWA.
4018 (define_insn_and_split "ashdi3_extswsli"
4019   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4020         (ashift:DI
4021          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4022          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4023   "TARGET_EXTSWSLI"
4024   "@
4025    extswsli %0,%1,%2
4026    #"
4027   "&& reload_completed && MEM_P (operands[1])"
4028   [(set (match_dup 3)
4029         (match_dup 1))
4030    (set (match_dup 0)
4031         (ashift:DI (sign_extend:DI (match_dup 3))
4032                    (match_dup 2)))]
4034   operands[3] = gen_lowpart (SImode, operands[0]);
4036   [(set_attr "type" "shift")
4037    (set_attr "maybe_var_shift" "no")])
4040 (define_insn_and_split "ashdi3_extswsli_dot"
4041   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4042         (compare:CC
4043          (ashift:DI
4044           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4045           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4046          (const_int 0)))
4047    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4048   "TARGET_EXTSWSLI"
4049   "@
4050    extswsli. %0,%1,%2
4051    #
4052    #
4053    #"
4054   "&& reload_completed
4055    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4056        || memory_operand (operands[1], SImode))"
4057   [(pc)]
4059   rtx dest = operands[0];
4060   rtx src = operands[1];
4061   rtx shift = operands[2];
4062   rtx cr = operands[3];
4063   rtx src2;
4065   if (!MEM_P (src))
4066     src2 = src;
4067   else
4068     {
4069       src2 = gen_lowpart (SImode, dest);
4070       emit_move_insn (src2, src);
4071     }
4073   if (REGNO (cr) == CR0_REGNO)
4074     {
4075       emit_insn (gen_ashdi3_extswsli_dot (dest, src2, shift, cr));
4076       DONE;
4077     }
4079   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4080   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4081   DONE;
4083   [(set_attr "type" "shift")
4084    (set_attr "maybe_var_shift" "no")
4085    (set_attr "dot" "yes")
4086    (set_attr "length" "4,8,8,12")])
4088 (define_insn_and_split "ashdi3_extswsli_dot2"
4089   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4090         (compare:CC
4091          (ashift:DI
4092           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4093           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4094          (const_int 0)))
4095    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4096         (ashift:DI (sign_extend:DI (match_dup 1))
4097                    (match_dup 2)))]
4098   "TARGET_EXTSWSLI"
4099   "@
4100    extswsli. %0,%1,%2
4101    #
4102    #
4103    #"
4104   "&& reload_completed
4105    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4106        || memory_operand (operands[1], SImode))"
4107   [(pc)]
4109   rtx dest = operands[0];
4110   rtx src = operands[1];
4111   rtx shift = operands[2];
4112   rtx cr = operands[3];
4113   rtx src2;
4115   if (!MEM_P (src))
4116     src2 = src;
4117   else
4118     {
4119       src2 = gen_lowpart (SImode, dest);
4120       emit_move_insn (src2, src);
4121     }
4123   if (REGNO (cr) == CR0_REGNO)
4124     {
4125       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4126       DONE;
4127     }
4129   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4130   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4131   DONE;
4133   [(set_attr "type" "shift")
4134    (set_attr "maybe_var_shift" "no")
4135    (set_attr "dot" "yes")
4136    (set_attr "length" "4,8,8,12")])
4138 (define_insn "lshr<mode>3"
4139   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4140         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4141                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4142   ""
4143   "sr<wd>%I2 %0,%1,%<hH>2"
4144   [(set_attr "type" "shift")
4145    (set_attr "maybe_var_shift" "yes")])
4147 (define_insn "*lshrsi3_64"
4148   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4149         (zero_extend:DI
4150             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4151                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4152   "TARGET_POWERPC64"
4153   "srw%I2 %0,%1,%h2"
4154   [(set_attr "type" "shift")
4155    (set_attr "maybe_var_shift" "yes")])
4157 (define_insn_and_split "*lshr<mode>3_dot"
4158   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4159         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4160                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4161                     (const_int 0)))
4162    (clobber (match_scratch:GPR 0 "=r,r"))]
4163   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4164   "@
4165    sr<wd>%I2. %0,%1,%<hH>2
4166    #"
4167   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4168   [(set (match_dup 0)
4169         (lshiftrt:GPR (match_dup 1)
4170                       (match_dup 2)))
4171    (set (match_dup 3)
4172         (compare:CC (match_dup 0)
4173                     (const_int 0)))]
4174   ""
4175   [(set_attr "type" "shift")
4176    (set_attr "maybe_var_shift" "yes")
4177    (set_attr "dot" "yes")
4178    (set_attr "length" "4,8")])
4180 (define_insn_and_split "*lshr<mode>3_dot2"
4181   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4182         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4183                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4184                     (const_int 0)))
4185    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4186         (lshiftrt:GPR (match_dup 1)
4187                       (match_dup 2)))]
4188   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4189   "@
4190    sr<wd>%I2. %0,%1,%<hH>2
4191    #"
4192   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4193   [(set (match_dup 0)
4194         (lshiftrt:GPR (match_dup 1)
4195                       (match_dup 2)))
4196    (set (match_dup 3)
4197         (compare:CC (match_dup 0)
4198                     (const_int 0)))]
4199   ""
4200   [(set_attr "type" "shift")
4201    (set_attr "maybe_var_shift" "yes")
4202    (set_attr "dot" "yes")
4203    (set_attr "length" "4,8")])
4206 (define_insn "ashr<mode>3"
4207   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4208         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4209                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4210    (clobber (reg:GPR CA_REGNO))]
4211   ""
4212   "sra<wd>%I2 %0,%1,%<hH>2"
4213   [(set_attr "type" "shift")
4214    (set_attr "maybe_var_shift" "yes")])
4216 (define_insn "*ashrsi3_64"
4217   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4218         (sign_extend:DI
4219             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4220                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4221    (clobber (reg:SI CA_REGNO))]
4222   "TARGET_POWERPC64"
4223   "sraw%I2 %0,%1,%h2"
4224   [(set_attr "type" "shift")
4225    (set_attr "maybe_var_shift" "yes")])
4227 (define_insn_and_split "*ashr<mode>3_dot"
4228   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4229         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4230                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4231                     (const_int 0)))
4232    (clobber (match_scratch:GPR 0 "=r,r"))
4233    (clobber (reg:GPR CA_REGNO))]
4234   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4235   "@
4236    sra<wd>%I2. %0,%1,%<hH>2
4237    #"
4238   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4239   [(parallel [(set (match_dup 0)
4240                    (ashiftrt:GPR (match_dup 1)
4241                                  (match_dup 2)))
4242               (clobber (reg:GPR CA_REGNO))])
4243    (set (match_dup 3)
4244         (compare:CC (match_dup 0)
4245                     (const_int 0)))]
4246   ""
4247   [(set_attr "type" "shift")
4248    (set_attr "maybe_var_shift" "yes")
4249    (set_attr "dot" "yes")
4250    (set_attr "length" "4,8")])
4252 (define_insn_and_split "*ashr<mode>3_dot2"
4253   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4254         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4255                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4256                     (const_int 0)))
4257    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4258         (ashiftrt:GPR (match_dup 1)
4259                       (match_dup 2)))
4260    (clobber (reg:GPR CA_REGNO))]
4261   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4262   "@
4263    sra<wd>%I2. %0,%1,%<hH>2
4264    #"
4265   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4266   [(parallel [(set (match_dup 0)
4267                    (ashiftrt:GPR (match_dup 1)
4268                                  (match_dup 2)))
4269               (clobber (reg:GPR CA_REGNO))])
4270    (set (match_dup 3)
4271         (compare:CC (match_dup 0)
4272                     (const_int 0)))]
4273   ""
4274   [(set_attr "type" "shift")
4275    (set_attr "maybe_var_shift" "yes")
4276    (set_attr "dot" "yes")
4277    (set_attr "length" "4,8")])
4279 ;; Builtins to replace a division to generate FRE reciprocal estimate
4280 ;; instructions and the necessary fixup instructions
4281 (define_expand "recip<mode>3"
4282   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4283    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4284    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4285   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4287    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4288    DONE;
4291 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4292 ;; hardware division.  This is only done before register allocation and with
4293 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4294 (define_split
4295   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4296         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4297                     (match_operand 2 "gpc_reg_operand" "")))]
4298   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4299    && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4300    && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4301   [(const_int 0)]
4303   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4304   DONE;
4307 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4308 ;; appropriate fixup.
4309 (define_expand "rsqrt<mode>2"
4310   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4311    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4312   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4314   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4315   DONE;
4318 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4319 ;; modes here, and also add in conditional vsx/power8-vector support to access
4320 ;; values in the traditional Altivec registers if the appropriate
4321 ;; -mupper-regs-{df,sf} option is enabled.
4323 (define_expand "abs<mode>2"
4324   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4325         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4326   "TARGET_<MODE>_INSN"
4327   "")
4329 (define_insn "*abs<mode>2_fpr"
4330   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4331         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4332   "TARGET_<MODE>_FPR"
4333   "@
4334    fabs %0,%1
4335    xsabsdp %x0,%x1"
4336   [(set_attr "type" "fp")
4337    (set_attr "fp_type" "fp_addsub_<Fs>")])
4339 (define_insn "*nabs<mode>2_fpr"
4340   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4341         (neg:SFDF
4342          (abs:SFDF
4343           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4344   "TARGET_<MODE>_FPR"
4345   "@
4346    fnabs %0,%1
4347    xsnabsdp %x0,%x1"
4348   [(set_attr "type" "fp")
4349    (set_attr "fp_type" "fp_addsub_<Fs>")])
4351 (define_expand "neg<mode>2"
4352   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4353         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4354   "TARGET_<MODE>_INSN"
4355   "")
4357 (define_insn "*neg<mode>2_fpr"
4358   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4359         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4360   "TARGET_<MODE>_FPR"
4361   "@
4362    fneg %0,%1
4363    xsnegdp %x0,%x1"
4364   [(set_attr "type" "fp")
4365    (set_attr "fp_type" "fp_addsub_<Fs>")])
4367 (define_expand "add<mode>3"
4368   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4369         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4370                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4371   "TARGET_<MODE>_INSN"
4372   "")
4374 (define_insn "*add<mode>3_fpr"
4375   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4376         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4377                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4378   "TARGET_<MODE>_FPR"
4379   "@
4380    fadd<Ftrad> %0,%1,%2
4381    xsadd<Fvsx> %x0,%x1,%x2"
4382   [(set_attr "type" "fp")
4383    (set_attr "fp_type" "fp_addsub_<Fs>")])
4385 (define_expand "sub<mode>3"
4386   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4387         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4388                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4389   "TARGET_<MODE>_INSN"
4390   "")
4392 (define_insn "*sub<mode>3_fpr"
4393   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4394         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4395                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4396   "TARGET_<MODE>_FPR"
4397   "@
4398    fsub<Ftrad> %0,%1,%2
4399    xssub<Fvsx> %x0,%x1,%x2"
4400   [(set_attr "type" "fp")
4401    (set_attr "fp_type" "fp_addsub_<Fs>")])
4403 (define_expand "mul<mode>3"
4404   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4405         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4406                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4407   "TARGET_<MODE>_INSN"
4408   "")
4410 (define_insn "*mul<mode>3_fpr"
4411   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4412         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4413                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4414   "TARGET_<MODE>_FPR"
4415   "@
4416    fmul<Ftrad> %0,%1,%2
4417    xsmul<Fvsx> %x0,%x1,%x2"
4418   [(set_attr "type" "dmul")
4419    (set_attr "fp_type" "fp_mul_<Fs>")])
4421 (define_expand "div<mode>3"
4422   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4423         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4424                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4425   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4426   "")
4428 (define_insn "*div<mode>3_fpr"
4429   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4430         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4431                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4432   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4433   "@
4434    fdiv<Ftrad> %0,%1,%2
4435    xsdiv<Fvsx> %x0,%x1,%x2"
4436   [(set_attr "type" "<Fs>div")
4437    (set_attr "fp_type" "fp_div_<Fs>")])
4439 (define_insn "*sqrt<mode>2_internal"
4440   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4441         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4442   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4443    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4444   "@
4445    fsqrt<Ftrad> %0,%1
4446    xssqrt<Fvsx> %x0,%x1"
4447   [(set_attr "type" "<Fs>sqrt")
4448    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4450 (define_expand "sqrt<mode>2"
4451   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4452         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4453   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4454    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4456   if (<MODE>mode == SFmode
4457       && TARGET_RECIP_PRECISION
4458       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4459       && !optimize_function_for_size_p (cfun)
4460       && flag_finite_math_only && !flag_trapping_math
4461       && flag_unsafe_math_optimizations)
4462     {
4463       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4464       DONE;
4465     }
4468 ;; Floating point reciprocal approximation
4469 (define_insn "fre<Fs>"
4470   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4471         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4472                      UNSPEC_FRES))]
4473   "TARGET_<FFRE>"
4474   "@
4475    fre<Ftrad> %0,%1
4476    xsre<Fvsx> %x0,%x1"
4477   [(set_attr "type" "fp")])
4479 (define_insn "*rsqrt<mode>2"
4480   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4481         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4482                      UNSPEC_RSQRT))]
4483   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4484   "@
4485    frsqrte<Ftrad> %0,%1
4486    xsrsqrte<Fvsx> %x0,%x1"
4487   [(set_attr "type" "fp")])
4489 ;; Floating point comparisons
4490 (define_insn "*cmp<mode>_fpr"
4491   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4492         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4493                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4494   "TARGET_<MODE>_FPR"
4495   "@
4496    fcmpu %0,%1,%2
4497    xscmpudp %0,%x1,%x2"
4498   [(set_attr "type" "fpcompare")])
4500 ;; Floating point conversions
4501 (define_expand "extendsfdf2"
4502   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4503         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4504   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4505   "")
4507 (define_insn_and_split "*extendsfdf2_fpr"
4508   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4509         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4510   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4511   "@
4512    #
4513    fmr %0,%1
4514    lfs%U1%X1 %0,%1
4515    #
4516    xscpsgndp %x0,%x1,%x1
4517    lxsspx %x0,%y1
4518    lxssp %0,%1"
4519   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4520   [(const_int 0)]
4522   emit_note (NOTE_INSN_DELETED);
4523   DONE;
4525   [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")])
4527 (define_expand "truncdfsf2"
4528   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4529         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4530   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4531   "")
4533 (define_insn "*truncdfsf2_fpr"
4534   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4535         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4536   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4537   "@
4538    frsp %0,%1
4539    xsrsp %x0,%x1"
4540   [(set_attr "type" "fp")])
4542 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4543 ;; builtins.c and optabs.c that are not correct for IBM long double
4544 ;; when little-endian.
4545 (define_expand "signbit<mode>2"
4546   [(set (match_dup 2)
4547         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
4548    (set (match_dup 3)
4549         (subreg:DI (match_dup 2) 0))
4550    (set (match_dup 4)
4551         (match_dup 5))
4552    (set (match_operand:SI 0 "gpc_reg_operand" "")
4553         (match_dup 6))]
4554   "TARGET_HARD_FLOAT
4555    && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4557   operands[2] = gen_reg_rtx (DFmode);
4558   operands[3] = gen_reg_rtx (DImode);
4559   if (TARGET_POWERPC64)
4560     {
4561       operands[4] = gen_reg_rtx (DImode);
4562       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4563       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4564                                     WORDS_BIG_ENDIAN ? 4 : 0);
4565     }
4566   else
4567     {
4568       operands[4] = gen_reg_rtx (SImode);
4569       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4570                                     WORDS_BIG_ENDIAN ? 0 : 4);
4571       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4572     }
4575 (define_expand "copysign<mode>3"
4576   [(set (match_dup 3)
4577         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4578    (set (match_dup 4)
4579         (neg:SFDF (abs:SFDF (match_dup 1))))
4580    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4581         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4582                                (match_dup 5))
4583                          (match_dup 3)
4584                          (match_dup 4)))]
4585   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4586    && ((TARGET_PPC_GFXOPT
4587         && !HONOR_NANS (<MODE>mode)
4588         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4589        || TARGET_CMPB
4590        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4592   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4593     {
4594       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4595                                              operands[2]));
4596       DONE;
4597     }
4599    operands[3] = gen_reg_rtx (<MODE>mode);
4600    operands[4] = gen_reg_rtx (<MODE>mode);
4601    operands[5] = CONST0_RTX (<MODE>mode);
4602   })
4604 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4605 ;; compiler from optimizing -0.0
4606 (define_insn "copysign<mode>3_fcpsgn"
4607   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4608         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4609                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4610                      UNSPEC_COPYSIGN))]
4611   "TARGET_<MODE>_FPR && TARGET_CMPB"
4612   "@
4613    fcpsgn %0,%2,%1
4614    xscpsgndp %x0,%x2,%x1"
4615   [(set_attr "type" "fp")])
4617 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4618 ;; fsel instruction and some auxiliary computations.  Then we just have a
4619 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4620 ;; combine.
4621 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4622 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4623 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4624 ;; define_splits to make them if made by combine.  On VSX machines we have the
4625 ;; min/max instructions.
4627 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4628 ;; to allow either DF/SF to use only traditional registers.
4630 (define_expand "smax<mode>3"
4631   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4632         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4633                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4634                            (match_dup 1)
4635                            (match_dup 2)))]
4636   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4638   rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4639   DONE;
4642 (define_insn "*smax<mode>3_vsx"
4643   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4644         (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4645                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4646   "TARGET_<MODE>_FPR && TARGET_VSX"
4647   "xsmaxdp %x0,%x1,%x2"
4648   [(set_attr "type" "fp")])
4650 (define_expand "smin<mode>3"
4651   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4652         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4653                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4654                            (match_dup 2)
4655                            (match_dup 1)))]
4656   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4658   rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4659   DONE;
4662 (define_insn "*smin<mode>3_vsx"
4663   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4664         (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4665                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4666   "TARGET_<MODE>_FPR && TARGET_VSX"
4667   "xsmindp %x0,%x1,%x2"
4668   [(set_attr "type" "fp")])
4670 (define_split
4671   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4672         (match_operator:SFDF 3 "min_max_operator"
4673          [(match_operand:SFDF 1 "gpc_reg_operand" "")
4674           (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4675   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4676    && !TARGET_VSX"
4677   [(const_int 0)]
4679   rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4680                       operands[2]);
4681   DONE;
4684 (define_split
4685   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4686         (match_operator:SF 3 "min_max_operator"
4687          [(match_operand:SF 1 "gpc_reg_operand" "")
4688           (match_operand:SF 2 "gpc_reg_operand" "")]))]
4689   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
4690    && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4691   [(const_int 0)]
4692   "
4693 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4694                       operands[1], operands[2]);
4695   DONE;
4698 (define_expand "mov<mode>cc"
4699    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4700          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4701                            (match_operand:GPR 2 "gpc_reg_operand" "")
4702                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4703   "TARGET_ISEL<sel>"
4704   "
4706   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4707     DONE;
4708   else
4709     FAIL;
4712 ;; We use the BASE_REGS for the isel input operands because, if rA is
4713 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4714 ;; because we may switch the operands and rB may end up being rA.
4716 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4717 ;; leave out the mode in operand 4 and use one pattern, but reload can
4718 ;; change the mode underneath our feet and then gets confused trying
4719 ;; to reload the value.
4720 (define_insn "isel_signed_<mode>"
4721   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4722         (if_then_else:GPR
4723          (match_operator 1 "scc_comparison_operator"
4724                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4725                           (const_int 0)])
4726          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4727          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4728   "TARGET_ISEL<sel>"
4729   "*
4730 { return output_isel (operands); }"
4731   [(set_attr "type" "isel")
4732    (set_attr "length" "4")])
4734 (define_insn "isel_unsigned_<mode>"
4735   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4736         (if_then_else:GPR
4737          (match_operator 1 "scc_comparison_operator"
4738                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4739                           (const_int 0)])
4740          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4741          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4742   "TARGET_ISEL<sel>"
4743   "*
4744 { return output_isel (operands); }"
4745   [(set_attr "type" "isel")
4746    (set_attr "length" "4")])
4748 ;; These patterns can be useful for combine; they let combine know that
4749 ;; isel can handle reversed comparisons so long as the operands are
4750 ;; registers.
4752 (define_insn "*isel_reversed_signed_<mode>"
4753   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4754         (if_then_else:GPR
4755          (match_operator 1 "scc_rev_comparison_operator"
4756                          [(match_operand:CC 4 "cc_reg_operand" "y")
4757                           (const_int 0)])
4758          (match_operand:GPR 2 "gpc_reg_operand" "b")
4759          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4760   "TARGET_ISEL<sel>"
4761   "*
4762 { return output_isel (operands); }"
4763   [(set_attr "type" "isel")
4764    (set_attr "length" "4")])
4766 (define_insn "*isel_reversed_unsigned_<mode>"
4767   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4768         (if_then_else:GPR
4769          (match_operator 1 "scc_rev_comparison_operator"
4770                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4771                           (const_int 0)])
4772          (match_operand:GPR 2 "gpc_reg_operand" "b")
4773          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4774   "TARGET_ISEL<sel>"
4775   "*
4776 { return output_isel (operands); }"
4777   [(set_attr "type" "isel")
4778    (set_attr "length" "4")])
4780 (define_expand "movsfcc"
4781    [(set (match_operand:SF 0 "gpc_reg_operand" "")
4782          (if_then_else:SF (match_operand 1 "comparison_operator" "")
4783                           (match_operand:SF 2 "gpc_reg_operand" "")
4784                           (match_operand:SF 3 "gpc_reg_operand" "")))]
4785   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4786   "
4788   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4789     DONE;
4790   else
4791     FAIL;
4794 (define_insn "*fselsfsf4"
4795   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4796         (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4797                              (match_operand:SF 4 "zero_fp_constant" "F"))
4798                          (match_operand:SF 2 "gpc_reg_operand" "f")
4799                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4800   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4801   "fsel %0,%1,%2,%3"
4802   [(set_attr "type" "fp")])
4804 (define_insn "*fseldfsf4"
4805   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4806         (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4807                              (match_operand:DF 4 "zero_fp_constant" "F"))
4808                          (match_operand:SF 2 "gpc_reg_operand" "f")
4809                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4810   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4811   "fsel %0,%1,%2,%3"
4812   [(set_attr "type" "fp")])
4814 ;; The conditional move instructions allow us to perform max and min
4815 ;; operations even when
4817 (define_split
4818   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4819         (match_operator:DF 3 "min_max_operator"
4820          [(match_operand:DF 1 "gpc_reg_operand" "")
4821           (match_operand:DF 2 "gpc_reg_operand" "")]))]
4822   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
4823    && !flag_trapping_math"
4824   [(const_int 0)]
4825   "
4826 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4827                       operands[1], operands[2]);
4828   DONE;
4831 (define_expand "movdfcc"
4832    [(set (match_operand:DF 0 "gpc_reg_operand" "")
4833          (if_then_else:DF (match_operand 1 "comparison_operator" "")
4834                           (match_operand:DF 2 "gpc_reg_operand" "")
4835                           (match_operand:DF 3 "gpc_reg_operand" "")))]
4836   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4837   "
4839   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4840     DONE;
4841   else
4842     FAIL;
4845 (define_insn "*fseldfdf4"
4846   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4847         (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4848                              (match_operand:DF 4 "zero_fp_constant" "F"))
4849                          (match_operand:DF 2 "gpc_reg_operand" "d")
4850                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4851   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4852   "fsel %0,%1,%2,%3"
4853   [(set_attr "type" "fp")])
4855 (define_insn "*fselsfdf4"
4856   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4857         (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4858                              (match_operand:SF 4 "zero_fp_constant" "F"))
4859                          (match_operand:DF 2 "gpc_reg_operand" "d")
4860                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4861   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4862   "fsel %0,%1,%2,%3"
4863   [(set_attr "type" "fp")])
4865 ;; Conversions to and from floating-point.
4867 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4868 ; don't want to support putting SImode in FPR registers.
4869 (define_insn "lfiwax"
4870   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4871         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4872                    UNSPEC_LFIWAX))]
4873   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4874   "@
4875    lfiwax %0,%y1
4876    lxsiwax %x0,%y1
4877    mtvsrwa %x0,%1"
4878   [(set_attr "type" "fpload,fpload,mffgpr")])
4880 ; This split must be run before register allocation because it allocates the
4881 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4882 ; it earlier to allow for the combiner to merge insns together where it might
4883 ; not be needed and also in case the insns are deleted as dead code.
4885 (define_insn_and_split "floatsi<mode>2_lfiwax"
4886   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4887         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4888    (clobber (match_scratch:DI 2 "=wj"))]
4889   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4890    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4891   "#"
4892   ""
4893   [(pc)]
4894   "
4896   rtx dest = operands[0];
4897   rtx src = operands[1];
4898   rtx tmp;
4900   if (!MEM_P (src) && TARGET_POWERPC64
4901       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4902     tmp = convert_to_mode (DImode, src, false);
4903   else
4904     {
4905       tmp = operands[2];
4906       if (GET_CODE (tmp) == SCRATCH)
4907         tmp = gen_reg_rtx (DImode);
4908       if (MEM_P (src))
4909         {
4910           src = rs6000_address_for_fpconvert (src);
4911           emit_insn (gen_lfiwax (tmp, src));
4912         }
4913       else
4914         {
4915           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4916           emit_move_insn (stack, src);
4917           emit_insn (gen_lfiwax (tmp, stack));
4918         }
4919     }
4920   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4921   DONE;
4923   [(set_attr "length" "12")
4924    (set_attr "type" "fpload")])
4926 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4927   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4928         (float:SFDF
4929          (sign_extend:DI
4930           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4931    (clobber (match_scratch:DI 2 "=0,d"))]
4932   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4933    && <SI_CONVERT_FP>"
4934   "#"
4935   ""
4936   [(pc)]
4937   "
4939   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4940   if (GET_CODE (operands[2]) == SCRATCH)
4941     operands[2] = gen_reg_rtx (DImode);
4942   emit_insn (gen_lfiwax (operands[2], operands[1]));
4943   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4944   DONE;
4946   [(set_attr "length" "8")
4947    (set_attr "type" "fpload")])
4949 (define_insn "lfiwzx"
4950   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4951         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4952                    UNSPEC_LFIWZX))]
4953   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4954   "@
4955    lfiwzx %0,%y1
4956    lxsiwzx %x0,%y1
4957    mtvsrwz %x0,%1"
4958   [(set_attr "type" "fpload,fpload,mftgpr")])
4960 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4961   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4962         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4963    (clobber (match_scratch:DI 2 "=wj"))]
4964   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4965    && <SI_CONVERT_FP>"
4966   "#"
4967   ""
4968   [(pc)]
4969   "
4971   rtx dest = operands[0];
4972   rtx src = operands[1];
4973   rtx tmp;
4975   if (!MEM_P (src) && TARGET_POWERPC64
4976       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4977     tmp = convert_to_mode (DImode, src, true);
4978   else
4979     {
4980       tmp = operands[2];
4981       if (GET_CODE (tmp) == SCRATCH)
4982         tmp = gen_reg_rtx (DImode);
4983       if (MEM_P (src))
4984         {
4985           src = rs6000_address_for_fpconvert (src);
4986           emit_insn (gen_lfiwzx (tmp, src));
4987         }
4988       else
4989         {
4990           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4991           emit_move_insn (stack, src);
4992           emit_insn (gen_lfiwzx (tmp, stack));
4993         }
4994     }
4995   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4996   DONE;
4998   [(set_attr "length" "12")
4999    (set_attr "type" "fpload")])
5001 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5002   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
5003         (unsigned_float:SFDF
5004          (zero_extend:DI
5005           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5006    (clobber (match_scratch:DI 2 "=0,d"))]
5007   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5008    && <SI_CONVERT_FP>"
5009   "#"
5010   ""
5011   [(pc)]
5012   "
5014   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5015   if (GET_CODE (operands[2]) == SCRATCH)
5016     operands[2] = gen_reg_rtx (DImode);
5017   emit_insn (gen_lfiwzx (operands[2], operands[1]));
5018   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5019   DONE;
5021   [(set_attr "length" "8")
5022    (set_attr "type" "fpload")])
5024 ; For each of these conversions, there is a define_expand, a define_insn
5025 ; with a '#' template, and a define_split (with C code).  The idea is
5026 ; to allow constant folding with the template of the define_insn,
5027 ; then to have the insns split later (between sched1 and final).
5029 (define_expand "floatsidf2"
5030   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5031                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5032               (use (match_dup 2))
5033               (use (match_dup 3))
5034               (clobber (match_dup 4))
5035               (clobber (match_dup 5))
5036               (clobber (match_dup 6))])]
5037   "TARGET_HARD_FLOAT 
5038    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5039   "
5041   if (TARGET_E500_DOUBLE)
5042     {
5043       if (!REG_P (operands[1]))
5044         operands[1] = force_reg (SImode, operands[1]);
5045       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5046       DONE;
5047     }
5048   else if (TARGET_LFIWAX && TARGET_FCFID)
5049     {
5050       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5051       DONE;
5052     }
5053   else if (TARGET_FCFID)
5054     {
5055       rtx dreg = operands[1];
5056       if (!REG_P (dreg))
5057         dreg = force_reg (SImode, dreg);
5058       dreg = convert_to_mode (DImode, dreg, false);
5059       emit_insn (gen_floatdidf2 (operands[0], dreg));
5060       DONE;
5061     }
5063   if (!REG_P (operands[1]))
5064     operands[1] = force_reg (SImode, operands[1]);
5065   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5066   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5067   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5068   operands[5] = gen_reg_rtx (DFmode);
5069   operands[6] = gen_reg_rtx (SImode);
5072 (define_insn_and_split "*floatsidf2_internal"
5073   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5074         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5075    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5076    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5077    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5078    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5079    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5080   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5081   "#"
5082   ""
5083   [(pc)]
5084   "
5086   rtx lowword, highword;
5087   gcc_assert (MEM_P (operands[4]));
5088   highword = adjust_address (operands[4], SImode, 0);
5089   lowword = adjust_address (operands[4], SImode, 4);
5090   if (! WORDS_BIG_ENDIAN)
5091     std::swap (lowword, highword);
5093   emit_insn (gen_xorsi3 (operands[6], operands[1],
5094                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5095   emit_move_insn (lowword, operands[6]);
5096   emit_move_insn (highword, operands[2]);
5097   emit_move_insn (operands[5], operands[4]);
5098   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5099   DONE;
5101   [(set_attr "length" "24")
5102    (set_attr "type" "fp")])
5104 ;; If we don't have a direct conversion to single precision, don't enable this
5105 ;; conversion for 32-bit without fast math, because we don't have the insn to
5106 ;; generate the fixup swizzle to avoid double rounding problems.
5107 (define_expand "floatunssisf2"
5108   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5109         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5110   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5111    && (!TARGET_FPRS
5112        || (TARGET_FPRS
5113            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5114                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5115                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5116   "
5118   if (!TARGET_FPRS)
5119     {
5120       if (!REG_P (operands[1]))
5121         operands[1] = force_reg (SImode, operands[1]);
5122     }
5123   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5124     {
5125       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5126       DONE;
5127     }
5128   else
5129     {
5130       rtx dreg = operands[1];
5131       if (!REG_P (dreg))
5132         dreg = force_reg (SImode, dreg);
5133       dreg = convert_to_mode (DImode, dreg, true);
5134       emit_insn (gen_floatdisf2 (operands[0], dreg));
5135       DONE;
5136     }
5139 (define_expand "floatunssidf2"
5140   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5141                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5142               (use (match_dup 2))
5143               (use (match_dup 3))
5144               (clobber (match_dup 4))
5145               (clobber (match_dup 5))])]
5146   "TARGET_HARD_FLOAT
5147    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5148   "
5150   if (TARGET_E500_DOUBLE)
5151     {
5152       if (!REG_P (operands[1]))
5153         operands[1] = force_reg (SImode, operands[1]);
5154       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5155       DONE;
5156     }
5157   else if (TARGET_LFIWZX && TARGET_FCFID)
5158     {
5159       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5160       DONE;
5161     }
5162   else if (TARGET_FCFID)
5163     {
5164       rtx dreg = operands[1];
5165       if (!REG_P (dreg))
5166         dreg = force_reg (SImode, dreg);
5167       dreg = convert_to_mode (DImode, dreg, true);
5168       emit_insn (gen_floatdidf2 (operands[0], dreg));
5169       DONE;
5170     }
5172   if (!REG_P (operands[1]))
5173     operands[1] = force_reg (SImode, operands[1]);
5174   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5175   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5176   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5177   operands[5] = gen_reg_rtx (DFmode);
5180 (define_insn_and_split "*floatunssidf2_internal"
5181   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5182         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5183    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5184    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5185    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5186    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5187   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5188    && !(TARGET_FCFID && TARGET_POWERPC64)"
5189   "#"
5190   ""
5191   [(pc)]
5192   "
5194   rtx lowword, highword;
5195   gcc_assert (MEM_P (operands[4]));
5196   highword = adjust_address (operands[4], SImode, 0);
5197   lowword = adjust_address (operands[4], SImode, 4);
5198   if (! WORDS_BIG_ENDIAN)
5199     std::swap (lowword, highword);
5201   emit_move_insn (lowword, operands[1]);
5202   emit_move_insn (highword, operands[2]);
5203   emit_move_insn (operands[5], operands[4]);
5204   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5205   DONE;
5207   [(set_attr "length" "20")
5208    (set_attr "type" "fp")])
5210 (define_expand "fix_trunc<mode>si2"
5211   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5212         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5213   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5214   "
5216   if (!<E500_CONVERT>)
5217     {
5218       rtx tmp, stack;
5220       if (TARGET_STFIWX)
5221         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5222       else
5223         {
5224           tmp = gen_reg_rtx (DImode);
5225           stack = rs6000_allocate_stack_temp (DImode, true, false);
5226           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5227                                                       tmp, stack));
5228         }
5229       DONE;
5230     }
5233 ; Like the convert to float patterns, this insn must be split before
5234 ; register allocation so that it can allocate the memory slot if it
5235 ; needed
5236 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5237   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5238         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5239    (clobber (match_scratch:DI 2 "=d"))]
5240   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5241    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5242    && TARGET_STFIWX && can_create_pseudo_p ()"
5243   "#"
5244   ""
5245   [(pc)]
5247   rtx dest = operands[0];
5248   rtx src = operands[1];
5249   rtx tmp = operands[2];
5251   if (GET_CODE (tmp) == SCRATCH)
5252     tmp = gen_reg_rtx (DImode);
5254   emit_insn (gen_fctiwz_<mode> (tmp, src));
5255   if (MEM_P (dest))
5256     {
5257       dest = rs6000_address_for_fpconvert (dest);
5258       emit_insn (gen_stfiwx (dest, tmp));
5259       DONE;
5260     }
5261   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5262     {
5263       dest = gen_lowpart (DImode, dest);
5264       emit_move_insn (dest, tmp);
5265       DONE;
5266     }
5267   else
5268     {
5269       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5270       emit_insn (gen_stfiwx (stack, tmp));
5271       emit_move_insn (dest, stack);
5272       DONE;
5273     }
5275   [(set_attr "length" "12")
5276    (set_attr "type" "fp")])
5278 (define_insn_and_split "fix_trunc<mode>si2_internal"
5279   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5280         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5281    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5282    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5283   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5284   "#"
5285   ""
5286   [(pc)]
5287   "
5289   rtx lowword;
5290   gcc_assert (MEM_P (operands[3]));
5291   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5293   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5294   emit_move_insn (operands[3], operands[2]);
5295   emit_move_insn (operands[0], lowword);
5296   DONE;
5298   [(set_attr "length" "16")
5299    (set_attr "type" "fp")])
5301 (define_expand "fix_trunc<mode>di2"
5302   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5303         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5304   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5305    && TARGET_FCFID"
5306   "")
5308 (define_insn "*fix_trunc<mode>di2_fctidz"
5309   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5310         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5311   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5312     && TARGET_FCFID"
5313   "@
5314    fctidz %0,%1
5315    xscvdpsxds %x0,%x1"
5316   [(set_attr "type" "fp")])
5318 (define_expand "fixuns_trunc<mode>si2"
5319   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5320         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5321   "TARGET_HARD_FLOAT
5322    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5323        || <E500_CONVERT>)"
5324   "
5326   if (!<E500_CONVERT>)
5327     {
5328       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5329       DONE;
5330     }
5333 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5334   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5335         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5336    (clobber (match_scratch:DI 2 "=d"))]
5337   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5338    && TARGET_STFIWX && can_create_pseudo_p ()"
5339   "#"
5340   ""
5341   [(pc)]
5343   rtx dest = operands[0];
5344   rtx src = operands[1];
5345   rtx tmp = operands[2];
5347   if (GET_CODE (tmp) == SCRATCH)
5348     tmp = gen_reg_rtx (DImode);
5350   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5351   if (MEM_P (dest))
5352     {
5353       dest = rs6000_address_for_fpconvert (dest);
5354       emit_insn (gen_stfiwx (dest, tmp));
5355       DONE;
5356     }
5357   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5358     {
5359       dest = gen_lowpart (DImode, dest);
5360       emit_move_insn (dest, tmp);
5361       DONE;
5362     }
5363   else
5364     {
5365       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5366       emit_insn (gen_stfiwx (stack, tmp));
5367       emit_move_insn (dest, stack);
5368       DONE;
5369     }
5371   [(set_attr "length" "12")
5372    (set_attr "type" "fp")])
5374 (define_expand "fixuns_trunc<mode>di2"
5375   [(set (match_operand:DI 0 "register_operand" "")
5376         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5377   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5378   "")
5380 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5381   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5382         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5383   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5384     && TARGET_FCTIDUZ"
5385   "@
5386    fctiduz %0,%1
5387    xscvdpuxds %x0,%x1"
5388   [(set_attr "type" "fp")])
5390 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5391 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5392 ; because the first makes it clear that operand 0 is not live
5393 ; before the instruction.
5394 (define_insn "fctiwz_<mode>"
5395   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5396         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5397                    UNSPEC_FCTIWZ))]
5398   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5399   "@
5400    fctiwz %0,%1
5401    xscvdpsxws %x0,%x1"
5402   [(set_attr "type" "fp")])
5404 (define_insn "fctiwuz_<mode>"
5405   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5406         (unspec:DI [(unsigned_fix:SI
5407                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5408                    UNSPEC_FCTIWUZ))]
5409   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5410   "@
5411    fctiwuz %0,%1
5412    xscvdpuxws %x0,%x1"
5413   [(set_attr "type" "fp")])
5415 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5416 ;; since the friz instruction does not truncate the value if the floating
5417 ;; point value is < LONG_MIN or > LONG_MAX.
5418 (define_insn "*friz"
5419   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5420         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5421   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5422    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5423   "@
5424    friz %0,%1
5425    xsrdpiz %x0,%x1"
5426   [(set_attr "type" "fp")])
5428 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5429 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5430 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5431 ;; extend it, store it back on the stack from the GPR, load it back into the
5432 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5433 ;; disable using store and load to sign/zero extend the value.
5434 (define_insn_and_split "*round32<mode>2_fprs"
5435   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5436         (float:SFDF
5437          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5438    (clobber (match_scratch:DI 2 "=d"))
5439    (clobber (match_scratch:DI 3 "=d"))]
5440   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5441    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5442    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5443   "#"
5444   ""
5445   [(pc)]
5447   rtx dest = operands[0];
5448   rtx src = operands[1];
5449   rtx tmp1 = operands[2];
5450   rtx tmp2 = operands[3];
5451   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5453   if (GET_CODE (tmp1) == SCRATCH)
5454     tmp1 = gen_reg_rtx (DImode);
5455   if (GET_CODE (tmp2) == SCRATCH)
5456     tmp2 = gen_reg_rtx (DImode);
5458   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5459   emit_insn (gen_stfiwx (stack, tmp1));
5460   emit_insn (gen_lfiwax (tmp2, stack));
5461   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5462   DONE;
5464   [(set_attr "type" "fpload")
5465    (set_attr "length" "16")])
5467 (define_insn_and_split "*roundu32<mode>2_fprs"
5468   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5469         (unsigned_float:SFDF
5470          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5471    (clobber (match_scratch:DI 2 "=d"))
5472    (clobber (match_scratch:DI 3 "=d"))]
5473   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5474    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5475    && can_create_pseudo_p ()"
5476   "#"
5477   ""
5478   [(pc)]
5480   rtx dest = operands[0];
5481   rtx src = operands[1];
5482   rtx tmp1 = operands[2];
5483   rtx tmp2 = operands[3];
5484   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5486   if (GET_CODE (tmp1) == SCRATCH)
5487     tmp1 = gen_reg_rtx (DImode);
5488   if (GET_CODE (tmp2) == SCRATCH)
5489     tmp2 = gen_reg_rtx (DImode);
5491   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5492   emit_insn (gen_stfiwx (stack, tmp1));
5493   emit_insn (gen_lfiwzx (tmp2, stack));
5494   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5495   DONE;
5497   [(set_attr "type" "fpload")
5498    (set_attr "length" "16")])
5500 ;; No VSX equivalent to fctid
5501 (define_insn "lrint<mode>di2"
5502   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5503         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5504                    UNSPEC_FCTID))]
5505   "TARGET_<MODE>_FPR && TARGET_FPRND"
5506   "fctid %0,%1"
5507   [(set_attr "type" "fp")])
5509 (define_insn "btrunc<mode>2"
5510   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5511         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5512                      UNSPEC_FRIZ))]
5513   "TARGET_<MODE>_FPR && TARGET_FPRND"
5514   "@
5515    friz %0,%1
5516    xsrdpiz %x0,%x1"
5517   [(set_attr "type" "fp")
5518    (set_attr "fp_type" "fp_addsub_<Fs>")])
5520 (define_insn "ceil<mode>2"
5521   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5522         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5523                      UNSPEC_FRIP))]
5524   "TARGET_<MODE>_FPR && TARGET_FPRND"
5525   "@
5526    frip %0,%1
5527    xsrdpip %x0,%x1"
5528   [(set_attr "type" "fp")
5529    (set_attr "fp_type" "fp_addsub_<Fs>")])
5531 (define_insn "floor<mode>2"
5532   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5533         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5534                      UNSPEC_FRIM))]
5535   "TARGET_<MODE>_FPR && TARGET_FPRND"
5536   "@
5537    frim %0,%1
5538    xsrdpim %x0,%x1"
5539   [(set_attr "type" "fp")
5540    (set_attr "fp_type" "fp_addsub_<Fs>")])
5542 ;; No VSX equivalent to frin
5543 (define_insn "round<mode>2"
5544   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5545         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5546                      UNSPEC_FRIN))]
5547   "TARGET_<MODE>_FPR && TARGET_FPRND"
5548   "frin %0,%1"
5549   [(set_attr "type" "fp")
5550    (set_attr "fp_type" "fp_addsub_<Fs>")])
5552 (define_insn "*xsrdpi<mode>2"
5553   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5554         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5555                      UNSPEC_XSRDPI))]
5556   "TARGET_<MODE>_FPR && TARGET_VSX"
5557   "xsrdpi %x0,%x1"
5558   [(set_attr "type" "fp")
5559    (set_attr "fp_type" "fp_addsub_<Fs>")])
5561 (define_expand "lround<mode>di2"
5562   [(set (match_dup 2)
5563         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5564                      UNSPEC_XSRDPI))
5565    (set (match_operand:DI 0 "gpc_reg_operand" "")
5566         (unspec:DI [(match_dup 2)]
5567                    UNSPEC_FCTID))]
5568   "TARGET_<MODE>_FPR && TARGET_VSX"
5570   operands[2] = gen_reg_rtx (<MODE>mode);
5573 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5574 (define_insn "stfiwx"
5575   [(set (match_operand:SI 0 "memory_operand" "=Z")
5576         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5577                    UNSPEC_STFIWX))]
5578   "TARGET_PPC_GFXOPT"
5579   "stfiwx %1,%y0"
5580   [(set_attr "type" "fpstore")])
5582 ;; If we don't have a direct conversion to single precision, don't enable this
5583 ;; conversion for 32-bit without fast math, because we don't have the insn to
5584 ;; generate the fixup swizzle to avoid double rounding problems.
5585 (define_expand "floatsisf2"
5586   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5587         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5588   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5589    && (!TARGET_FPRS
5590        || (TARGET_FPRS
5591            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5592                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5593                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5594   "
5596   if (!TARGET_FPRS)
5597     {
5598       if (!REG_P (operands[1]))
5599         operands[1] = force_reg (SImode, operands[1]);
5600     }
5601   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5602     {
5603       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5604       DONE;
5605     }
5606   else if (TARGET_FCFID && TARGET_LFIWAX)
5607     {
5608       rtx dfreg = gen_reg_rtx (DFmode);
5609       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5610       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5611       DONE;
5612     }
5613   else
5614     {
5615       rtx dreg = operands[1];
5616       if (!REG_P (dreg))
5617         dreg = force_reg (SImode, dreg);
5618       dreg = convert_to_mode (DImode, dreg, false);
5619       emit_insn (gen_floatdisf2 (operands[0], dreg));
5620       DONE;
5621     }
5624 (define_expand "floatdidf2"
5625   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5626         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5627   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5628   "")
5630 (define_insn "*floatdidf2_fpr"
5631   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5632         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5633   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5634   "@
5635    fcfid %0,%1
5636    xscvsxddp %x0,%x1"
5637   [(set_attr "type" "fp")])
5639 ; Allow the combiner to merge source memory operands to the conversion so that
5640 ; the optimizer/register allocator doesn't try to load the value too early in a
5641 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5642 ; hit.  We will split after reload to avoid the trip through the GPRs
5644 (define_insn_and_split "*floatdidf2_mem"
5645   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5646         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5647    (clobber (match_scratch:DI 2 "=d,wi"))]
5648   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5649   "#"
5650   "&& reload_completed"
5651   [(set (match_dup 2) (match_dup 1))
5652    (set (match_dup 0) (float:DF (match_dup 2)))]
5653   ""
5654   [(set_attr "length" "8")
5655    (set_attr "type" "fpload")])
5657 (define_expand "floatunsdidf2"
5658   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5659         (unsigned_float:DF
5660          (match_operand:DI 1 "gpc_reg_operand" "")))]
5661   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5662   "")
5664 (define_insn "*floatunsdidf2_fcfidu"
5665   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5666         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5667   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5668   "@
5669    fcfidu %0,%1
5670    xscvuxddp %x0,%x1"
5671   [(set_attr "type" "fp")
5672    (set_attr "length" "4")])
5674 (define_insn_and_split "*floatunsdidf2_mem"
5675   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5676         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5677    (clobber (match_scratch:DI 2 "=d,wi"))]
5678   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5679   "#"
5680   "&& reload_completed"
5681   [(set (match_dup 2) (match_dup 1))
5682    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5683   ""
5684   [(set_attr "length" "8")
5685    (set_attr "type" "fpload")])
5687 (define_expand "floatdisf2"
5688   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5689         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5690   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5691    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5692   "
5694   if (!TARGET_FCFIDS)
5695     {
5696       rtx val = operands[1];
5697       if (!flag_unsafe_math_optimizations)
5698         {
5699           rtx label = gen_label_rtx ();
5700           val = gen_reg_rtx (DImode);
5701           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5702           emit_label (label);
5703         }
5704       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5705       DONE;
5706     }
5709 (define_insn "floatdisf2_fcfids"
5710   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5711         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5712   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5713    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5714   "@
5715    fcfids %0,%1
5716    xscvsxdsp %x0,%x1"
5717   [(set_attr "type" "fp")])
5719 (define_insn_and_split "*floatdisf2_mem"
5720   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5721         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5722    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5723   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5724    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5725   "#"
5726   "&& reload_completed"
5727   [(pc)]
5728   "
5730   emit_move_insn (operands[2], operands[1]);
5731   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5732   DONE;
5734   [(set_attr "length" "8")])
5736 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5737 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5738 ;; from double rounding.
5739 ;; Instead of creating a new cpu type for two FP operations, just use fp
5740 (define_insn_and_split "floatdisf2_internal1"
5741   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5742         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5743    (clobber (match_scratch:DF 2 "=d"))]
5744   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5745    && !TARGET_FCFIDS"
5746   "#"
5747   "&& reload_completed"
5748   [(set (match_dup 2)
5749         (float:DF (match_dup 1)))
5750    (set (match_dup 0)
5751         (float_truncate:SF (match_dup 2)))]
5752   ""
5753   [(set_attr "length" "8")
5754    (set_attr "type" "fp")])
5756 ;; Twiddles bits to avoid double rounding.
5757 ;; Bits that might be truncated when converting to DFmode are replaced
5758 ;; by a bit that won't be lost at that stage, but is below the SFmode
5759 ;; rounding position.
5760 (define_expand "floatdisf2_internal2"
5761   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5762                                               (const_int 53)))
5763               (clobber (reg:DI CA_REGNO))])
5764    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5765                                            (const_int 2047)))
5766    (set (match_dup 3) (plus:DI (match_dup 3)
5767                                (const_int 1)))
5768    (set (match_dup 0) (plus:DI (match_dup 0)
5769                                (const_int 2047)))
5770    (set (match_dup 4) (compare:CCUNS (match_dup 3)
5771                                      (const_int 2)))
5772    (set (match_dup 0) (ior:DI (match_dup 0)
5773                               (match_dup 1)))
5774    (set (match_dup 0) (and:DI (match_dup 0)
5775                               (const_int -2048)))
5776    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5777                            (label_ref (match_operand:DI 2 "" ""))
5778                            (pc)))
5779    (set (match_dup 0) (match_dup 1))]
5780   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5781    && !TARGET_FCFIDS"
5782   "
5784   operands[3] = gen_reg_rtx (DImode);
5785   operands[4] = gen_reg_rtx (CCUNSmode);
5788 (define_expand "floatunsdisf2"
5789   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5790         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5791   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5792    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5793   "")
5795 (define_insn "floatunsdisf2_fcfidus"
5796   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5797         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5798   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5799    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5800   "@
5801    fcfidus %0,%1
5802    xscvuxdsp %x0,%x1"
5803   [(set_attr "type" "fp")])
5805 (define_insn_and_split "*floatunsdisf2_mem"
5806   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5807         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5808    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5809   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5810    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5811   "#"
5812   "&& reload_completed"
5813   [(pc)]
5814   "
5816   emit_move_insn (operands[2], operands[1]);
5817   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5818   DONE;
5820   [(set_attr "length" "8")
5821    (set_attr "type" "fpload")])
5823 ;; Define the TImode operations that can be done in a small number
5824 ;; of instructions.  The & constraints are to prevent the register
5825 ;; allocator from allocating registers that overlap with the inputs
5826 ;; (for example, having an input in 7,8 and an output in 6,7).  We
5827 ;; also allow for the output being the same as one of the inputs.
5829 (define_expand "addti3"
5830   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5831         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5832                  (match_operand:TI 2 "reg_or_short_operand" "")))]
5833   "TARGET_64BIT"
5835   rtx lo0 = gen_lowpart (DImode, operands[0]);
5836   rtx lo1 = gen_lowpart (DImode, operands[1]);
5837   rtx lo2 = gen_lowpart (DImode, operands[2]);
5838   rtx hi0 = gen_highpart (DImode, operands[0]);
5839   rtx hi1 = gen_highpart (DImode, operands[1]);
5840   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5842   if (!reg_or_short_operand (lo2, DImode))
5843     lo2 = force_reg (DImode, lo2);
5844   if (!adde_operand (hi2, DImode))
5845     hi2 = force_reg (DImode, hi2);
5847   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5848   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5849   DONE;
5852 (define_expand "subti3"
5853   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5854         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5855                   (match_operand:TI 2 "gpc_reg_operand" "")))]
5856   "TARGET_64BIT"
5858   rtx lo0 = gen_lowpart (DImode, operands[0]);
5859   rtx lo1 = gen_lowpart (DImode, operands[1]);
5860   rtx lo2 = gen_lowpart (DImode, operands[2]);
5861   rtx hi0 = gen_highpart (DImode, operands[0]);
5862   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5863   rtx hi2 = gen_highpart (DImode, operands[2]);
5865   if (!reg_or_short_operand (lo1, DImode))
5866     lo1 = force_reg (DImode, lo1);
5867   if (!adde_operand (hi1, DImode))
5868     hi1 = force_reg (DImode, hi1);
5870   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5871   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5872   DONE;
5875 ;; 128-bit logical operations expanders
5877 (define_expand "and<mode>3"
5878   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5879         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5880                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5881   ""
5882   "")
5884 (define_expand "ior<mode>3"
5885   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5886         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5887                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5888   ""
5889   "")
5891 (define_expand "xor<mode>3"
5892   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5893         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5894                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5895   ""
5896   "")
5898 (define_expand "one_cmpl<mode>2"
5899   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5900         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5901   ""
5902   "")
5904 (define_expand "nor<mode>3"
5905   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5906         (and:BOOL_128
5907          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5908          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5909   ""
5910   "")
5912 (define_expand "andc<mode>3"
5913   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5914         (and:BOOL_128
5915          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5916          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5917   ""
5918   "")
5920 ;; Power8 vector logical instructions.
5921 (define_expand "eqv<mode>3"
5922   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5923         (not:BOOL_128
5924          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5925                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5926   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5927   "")
5929 ;; Rewrite nand into canonical form
5930 (define_expand "nand<mode>3"
5931   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5932         (ior:BOOL_128
5933          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5934          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5935   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5936   "")
5938 ;; The canonical form is to have the negated element first, so we need to
5939 ;; reverse arguments.
5940 (define_expand "orc<mode>3"
5941   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5942         (ior:BOOL_128
5943          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5944          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5945   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5946   "")
5948 ;; 128-bit logical operations insns and split operations
5949 (define_insn_and_split "*and<mode>3_internal"
5950   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5951         (and:BOOL_128
5952          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5953          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
5954   ""
5956   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5957     return "xxland %x0,%x1,%x2";
5959   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5960     return "vand %0,%1,%2";
5962   return "#";
5964   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5965   [(const_int 0)]
5967   rs6000_split_logical (operands, AND, false, false, false);
5968   DONE;
5970   [(set (attr "type")
5971       (if_then_else
5972         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5973         (const_string "vecsimple")
5974         (const_string "integer")))
5975    (set (attr "length")
5976       (if_then_else
5977         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5978         (const_string "4")
5979         (if_then_else
5980          (match_test "TARGET_POWERPC64")
5981          (const_string "8")
5982          (const_string "16"))))])
5984 ;; 128-bit IOR/XOR
5985 (define_insn_and_split "*bool<mode>3_internal"
5986   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5987         (match_operator:BOOL_128 3 "boolean_or_operator"
5988          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5989           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
5990   ""
5992   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5993     return "xxl%q3 %x0,%x1,%x2";
5995   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5996     return "v%q3 %0,%1,%2";
5998   return "#";
6000   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6001   [(const_int 0)]
6003   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6004   DONE;
6006   [(set (attr "type")
6007       (if_then_else
6008         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6009         (const_string "vecsimple")
6010         (const_string "integer")))
6011    (set (attr "length")
6012       (if_then_else
6013         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6014         (const_string "4")
6015         (if_then_else
6016          (match_test "TARGET_POWERPC64")
6017          (const_string "8")
6018          (const_string "16"))))])
6020 ;; 128-bit ANDC/ORC
6021 (define_insn_and_split "*boolc<mode>3_internal1"
6022   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6023         (match_operator:BOOL_128 3 "boolean_operator"
6024          [(not:BOOL_128
6025            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6026           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6027   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6029   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6030     return "xxl%q3 %x0,%x1,%x2";
6032   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6033     return "v%q3 %0,%1,%2";
6035   return "#";
6037   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6038    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6039   [(const_int 0)]
6041   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6042   DONE;
6044   [(set (attr "type")
6045       (if_then_else
6046         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6047         (const_string "vecsimple")
6048         (const_string "integer")))
6049    (set (attr "length")
6050       (if_then_else
6051         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6052         (const_string "4")
6053         (if_then_else
6054          (match_test "TARGET_POWERPC64")
6055          (const_string "8")
6056          (const_string "16"))))])
6058 (define_insn_and_split "*boolc<mode>3_internal2"
6059   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6060         (match_operator:TI2 3 "boolean_operator"
6061          [(not:TI2
6062            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6063           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6064   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6065   "#"
6066   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6067   [(const_int 0)]
6069   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6070   DONE;
6072   [(set_attr "type" "integer")
6073    (set (attr "length")
6074         (if_then_else
6075          (match_test "TARGET_POWERPC64")
6076          (const_string "8")
6077          (const_string "16")))])
6079 ;; 128-bit NAND/NOR
6080 (define_insn_and_split "*boolcc<mode>3_internal1"
6081   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6082         (match_operator:BOOL_128 3 "boolean_operator"
6083          [(not:BOOL_128
6084            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6085           (not:BOOL_128
6086            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6087   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6089   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6090     return "xxl%q3 %x0,%x1,%x2";
6092   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6093     return "v%q3 %0,%1,%2";
6095   return "#";
6097   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6098    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6099   [(const_int 0)]
6101   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6102   DONE;
6104   [(set (attr "type")
6105       (if_then_else
6106         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6107         (const_string "vecsimple")
6108         (const_string "integer")))
6109    (set (attr "length")
6110       (if_then_else
6111         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6112         (const_string "4")
6113         (if_then_else
6114          (match_test "TARGET_POWERPC64")
6115          (const_string "8")
6116          (const_string "16"))))])
6118 (define_insn_and_split "*boolcc<mode>3_internal2"
6119   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6120         (match_operator:TI2 3 "boolean_operator"
6121          [(not:TI2
6122            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6123           (not:TI2
6124            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6125   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6126   "#"
6127   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6128   [(const_int 0)]
6130   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6131   DONE;
6133   [(set_attr "type" "integer")
6134    (set (attr "length")
6135         (if_then_else
6136          (match_test "TARGET_POWERPC64")
6137          (const_string "8")
6138          (const_string "16")))])
6141 ;; 128-bit EQV
6142 (define_insn_and_split "*eqv<mode>3_internal1"
6143   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6144         (not:BOOL_128
6145          (xor:BOOL_128
6146           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6147           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6148   "TARGET_P8_VECTOR"
6150   if (vsx_register_operand (operands[0], <MODE>mode))
6151     return "xxleqv %x0,%x1,%x2";
6153   return "#";
6155   "TARGET_P8_VECTOR && reload_completed
6156    && int_reg_operand (operands[0], <MODE>mode)"
6157   [(const_int 0)]
6159   rs6000_split_logical (operands, XOR, true, false, false);
6160   DONE;
6162   [(set (attr "type")
6163       (if_then_else
6164         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6165         (const_string "vecsimple")
6166         (const_string "integer")))
6167    (set (attr "length")
6168       (if_then_else
6169         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6170         (const_string "4")
6171         (if_then_else
6172          (match_test "TARGET_POWERPC64")
6173          (const_string "8")
6174          (const_string "16"))))])
6176 (define_insn_and_split "*eqv<mode>3_internal2"
6177   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6178         (not:TI2
6179          (xor:TI2
6180           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6181           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6182   "!TARGET_P8_VECTOR"
6183   "#"
6184   "reload_completed && !TARGET_P8_VECTOR"
6185   [(const_int 0)]
6187   rs6000_split_logical (operands, XOR, true, false, false);
6188   DONE;
6190   [(set_attr "type" "integer")
6191    (set (attr "length")
6192         (if_then_else
6193          (match_test "TARGET_POWERPC64")
6194          (const_string "8")
6195          (const_string "16")))])
6197 ;; 128-bit one's complement
6198 (define_insn_and_split "*one_cmpl<mode>3_internal"
6199   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6200         (not:BOOL_128
6201           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6202   ""
6204   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6205     return "xxlnor %x0,%x1,%x1";
6207   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6208     return "vnor %0,%1,%1";
6210   return "#";
6212   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6213   [(const_int 0)]
6215   rs6000_split_logical (operands, NOT, false, false, false);
6216   DONE;
6218   [(set (attr "type")
6219       (if_then_else
6220         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6221         (const_string "vecsimple")
6222         (const_string "integer")))
6223    (set (attr "length")
6224       (if_then_else
6225         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6226         (const_string "4")
6227         (if_then_else
6228          (match_test "TARGET_POWERPC64")
6229          (const_string "8")
6230          (const_string "16"))))])
6233 ;; Now define ways of moving data around.
6235 ;; Set up a register with a value from the GOT table
6237 (define_expand "movsi_got"
6238   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6239         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6240                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6241   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6242   "
6244   if (GET_CODE (operands[1]) == CONST)
6245     {
6246       rtx offset = const0_rtx;
6247       HOST_WIDE_INT value;
6249       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6250       value = INTVAL (offset);
6251       if (value != 0)
6252         {
6253           rtx tmp = (!can_create_pseudo_p ()
6254                      ? operands[0]
6255                      : gen_reg_rtx (Pmode));
6256           emit_insn (gen_movsi_got (tmp, operands[1]));
6257           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6258           DONE;
6259         }
6260     }
6262   operands[2] = rs6000_got_register (operands[1]);
6265 (define_insn "*movsi_got_internal"
6266   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6267         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6268                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6269                    UNSPEC_MOVSI_GOT))]
6270   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6271   "lwz %0,%a1@got(%2)"
6272   [(set_attr "type" "load")])
6274 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6275 ;; didn't get allocated to a hard register.
6276 (define_split
6277   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6278         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6279                     (match_operand:SI 2 "memory_operand" "")]
6280                    UNSPEC_MOVSI_GOT))]
6281   "DEFAULT_ABI == ABI_V4
6282     && flag_pic == 1
6283     && (reload_in_progress || reload_completed)"
6284   [(set (match_dup 0) (match_dup 2))
6285    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6286                                  UNSPEC_MOVSI_GOT))]
6287   "")
6289 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6290 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6291 ;; and this is even supposed to be faster, but it is simpler not to get
6292 ;; integers in the TOC.
6293 (define_insn "movsi_low"
6294   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6295         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6296                            (match_operand 2 "" ""))))]
6297   "TARGET_MACHO && ! TARGET_64BIT"
6298   "lwz %0,lo16(%2)(%1)"
6299   [(set_attr "type" "load")
6300    (set_attr "length" "4")])
6302 (define_insn "*movsi_internal1"
6303   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6304         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6305   "!TARGET_SINGLE_FPU &&
6306    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6307   "@
6308    mr %0,%1
6309    la %0,%a1
6310    lwz%U1%X1 %0,%1
6311    stw%U0%X0 %1,%0
6312    li %0,%1
6313    lis %0,%v1
6314    #
6315    mf%1 %0
6316    mt%0 %1
6317    mt%0 %1
6318    nop"
6319   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6320    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6322 (define_insn "*movsi_internal1_single"
6323   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6324         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6325   "TARGET_SINGLE_FPU &&
6326    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6327   "@
6328    mr %0,%1
6329    la %0,%a1
6330    lwz%U1%X1 %0,%1
6331    stw%U0%X0 %1,%0
6332    li %0,%1
6333    lis %0,%v1
6334    #
6335    mf%1 %0
6336    mt%0 %1
6337    mt%0 %1
6338    nop
6339    stfs%U0%X0 %1,%0
6340    lfs%U1%X1 %0,%1"
6341   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6342    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6344 ;; Split a load of a large constant into the appropriate two-insn
6345 ;; sequence.
6347 (define_split
6348   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6349         (match_operand:SI 1 "const_int_operand" ""))]
6350   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6351    && (INTVAL (operands[1]) & 0xffff) != 0"
6352   [(set (match_dup 0)
6353         (match_dup 2))
6354    (set (match_dup 0)
6355         (ior:SI (match_dup 0)
6356                 (match_dup 3)))]
6357   "
6359   if (rs6000_emit_set_const (operands[0], operands[1]))
6360     DONE;
6361   else
6362     FAIL;
6365 (define_insn "*mov<mode>_internal2"
6366   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6367         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6368                     (const_int 0)))
6369    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6370   ""
6371   "@
6372    cmp<wd>i %2,%0,0
6373    mr. %0,%1
6374    #"
6375   [(set_attr "type" "cmp,logical,cmp")
6376    (set_attr "dot" "yes")
6377    (set_attr "length" "4,4,8")])
6379 (define_split
6380   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6381         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6382                     (const_int 0)))
6383    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6384   "reload_completed"
6385   [(set (match_dup 0) (match_dup 1))
6386    (set (match_dup 2)
6387         (compare:CC (match_dup 0)
6388                     (const_int 0)))]
6389   "")
6391 (define_insn "*movhi_internal"
6392   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6393         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6394   "gpc_reg_operand (operands[0], HImode)
6395    || gpc_reg_operand (operands[1], HImode)"
6396   "@
6397    mr %0,%1
6398    lhz%U1%X1 %0,%1
6399    sth%U0%X0 %1,%0
6400    li %0,%w1
6401    mf%1 %0
6402    mt%0 %1
6403    nop"
6404   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6406 (define_expand "mov<mode>"
6407   [(set (match_operand:INT 0 "general_operand" "")
6408         (match_operand:INT 1 "any_operand" ""))]
6409   ""
6410   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6412 (define_insn "*movqi_internal"
6413   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6414         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6415   "gpc_reg_operand (operands[0], QImode)
6416    || gpc_reg_operand (operands[1], QImode)"
6417   "@
6418    mr %0,%1
6419    lbz%U1%X1 %0,%1
6420    stb%U0%X0 %1,%0
6421    li %0,%1
6422    mf%1 %0
6423    mt%0 %1
6424    nop"
6425   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6427 ;; Here is how to move condition codes around.  When we store CC data in
6428 ;; an integer register or memory, we store just the high-order 4 bits.
6429 ;; This lets us not shift in the most common case of CR0.
6430 (define_expand "movcc"
6431   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6432         (match_operand:CC 1 "nonimmediate_operand" ""))]
6433   ""
6434   "")
6436 (define_insn "*movcc_internal1"
6437   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6438         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6439   "register_operand (operands[0], CCmode)
6440    || register_operand (operands[1], CCmode)"
6441   "@
6442    mcrf %0,%1
6443    mtcrf 128,%1
6444    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6445    crxor %0,%0,%0
6446    mfcr %0%Q1
6447    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6448    mr %0,%1
6449    li %0,%1
6450    mf%1 %0
6451    mt%0 %1
6452    lwz%U1%X1 %0,%1
6453    stw%U0%X0 %1,%0"
6454   [(set (attr "type")
6455      (cond [(eq_attr "alternative" "0,3")
6456                 (const_string "cr_logical")
6457             (eq_attr "alternative" "1,2")
6458                 (const_string "mtcr")
6459             (eq_attr "alternative" "6,7")
6460                 (const_string "integer")
6461             (eq_attr "alternative" "8")
6462                 (const_string "mfjmpr")
6463             (eq_attr "alternative" "9")
6464                 (const_string "mtjmpr")
6465             (eq_attr "alternative" "10")
6466                 (const_string "load")
6467             (eq_attr "alternative" "11")
6468                 (const_string "store")
6469             (match_test "TARGET_MFCRF")
6470                 (const_string "mfcrf")
6471            ]
6472         (const_string "mfcr")))
6473    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6475 ;; For floating-point, we normally deal with the floating-point registers
6476 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6477 ;; can produce floating-point values in fixed-point registers.  Unless the
6478 ;; value is a simple constant or already in memory, we deal with this by
6479 ;; allocating memory and copying the value explicitly via that memory location.
6481 ;; Move 32-bit binary/decimal floating point
6482 (define_expand "mov<mode>"
6483   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6484         (match_operand:FMOVE32 1 "any_operand" ""))]
6485   "<fmove_ok>"
6486   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6488 (define_split
6489   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6490         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6491   "reload_completed
6492    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6493        || (GET_CODE (operands[0]) == SUBREG
6494            && GET_CODE (SUBREG_REG (operands[0])) == REG
6495            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6496   [(set (match_dup 2) (match_dup 3))]
6497   "
6499   long l;
6501   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6503   if (! TARGET_POWERPC64)
6504     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6505   else
6506     operands[2] = gen_lowpart (SImode, operands[0]);
6508   operands[3] = gen_int_mode (l, SImode);
6511 (define_insn "mov<mode>_hardfloat"
6512   [(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")
6513         (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"))]
6514   "(gpc_reg_operand (operands[0], <MODE>mode)
6515    || gpc_reg_operand (operands[1], <MODE>mode))
6516    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6517   "@
6518    mr %0,%1
6519    lwz%U1%X1 %0,%1
6520    stw%U0%X0 %1,%0
6521    fmr %0,%1
6522    xscpsgndp %x0,%x1,%x1
6523    xxlxor %x0,%x0,%x0
6524    li %0,0
6525    <f32_li>
6526    <f32_li2>
6527    <f32_si>
6528    <f32_si2>
6529    <f32_lv>
6530    <f32_sv>
6531    mtvsrwz %x0,%1
6532    mfvsrwz %0,%x1
6533    mt%0 %1
6534    mf%1 %0
6535    nop"
6536   [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
6537    (set_attr "length" "4")])
6539 (define_insn "*mov<mode>_softfloat"
6540   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6541         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6542   "(gpc_reg_operand (operands[0], <MODE>mode)
6543    || gpc_reg_operand (operands[1], <MODE>mode))
6544    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6545   "@
6546    mr %0,%1
6547    mt%0 %1
6548    mf%1 %0
6549    lwz%U1%X1 %0,%1
6550    stw%U0%X0 %1,%0
6551    li %0,%1
6552    lis %0,%v1
6553    #
6554    #
6555    nop"
6556   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6557    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6560 ;; Move 64-bit binary/decimal floating point
6561 (define_expand "mov<mode>"
6562   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6563         (match_operand:FMOVE64 1 "any_operand" ""))]
6564   ""
6565   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6567 (define_split
6568   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6569         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6570   "! TARGET_POWERPC64 && reload_completed
6571    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6572        || (GET_CODE (operands[0]) == SUBREG
6573            && GET_CODE (SUBREG_REG (operands[0])) == REG
6574            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6575   [(set (match_dup 2) (match_dup 4))
6576    (set (match_dup 3) (match_dup 1))]
6577   "
6579   int endian = (WORDS_BIG_ENDIAN == 0);
6580   HOST_WIDE_INT value = INTVAL (operands[1]);
6582   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6583   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6584   operands[4] = GEN_INT (value >> 32);
6585   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6588 (define_split
6589   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6590         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6591   "! TARGET_POWERPC64 && reload_completed
6592    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6593        || (GET_CODE (operands[0]) == SUBREG
6594            && GET_CODE (SUBREG_REG (operands[0])) == REG
6595            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6596   [(set (match_dup 2) (match_dup 4))
6597    (set (match_dup 3) (match_dup 5))]
6598   "
6600   int endian = (WORDS_BIG_ENDIAN == 0);
6601   long l[2];
6603   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6605   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6606   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6607   operands[4] = gen_int_mode (l[endian], SImode);
6608   operands[5] = gen_int_mode (l[1 - endian], SImode);
6611 (define_split
6612   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6613         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6614   "TARGET_POWERPC64 && reload_completed
6615    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6616        || (GET_CODE (operands[0]) == SUBREG
6617            && GET_CODE (SUBREG_REG (operands[0])) == REG
6618            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6619   [(set (match_dup 2) (match_dup 3))]
6620   "
6622   int endian = (WORDS_BIG_ENDIAN == 0);
6623   long l[2];
6624   HOST_WIDE_INT val;
6626   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6628   operands[2] = gen_lowpart (DImode, operands[0]);
6629   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6630   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6631          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6633   operands[3] = gen_int_mode (val, DImode);
6636 ;; Don't have reload use general registers to load a constant.  It is
6637 ;; less efficient than loading the constant into an FP register, since
6638 ;; it will probably be used there.
6640 ;; The move constraints are ordered to prefer floating point registers before
6641 ;; general purpose registers to avoid doing a store and a load to get the value
6642 ;; into a floating point register when it is needed for a floating point
6643 ;; operation.  Prefer traditional floating point registers over VSX registers,
6644 ;; since the D-form version of the memory instructions does not need a GPR for
6645 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6646 ;; registers.
6648 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6649 ;; except for 0.0 which can be created on VSX with an xor instruction.
6651 (define_insn "*mov<mode>_hardfloat32"
6652   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,o,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6653         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,o,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6654   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6655    && (gpc_reg_operand (operands[0], <MODE>mode)
6656        || gpc_reg_operand (operands[1], <MODE>mode))"
6657   "@
6658    stfd%U0%X0 %1,%0
6659    lfd%U1%X1 %0,%1
6660    fmr %0,%1
6661    lxsd%U1x %x0,%y1
6662    stxsd%U0x %x1,%y0
6663    lxsd %0,%1
6664    stxsd %1,%0
6665    xxlor %x0,%x1,%x1
6666    xxlxor %x0,%x0,%x0
6667    #
6668    #
6669    #
6670    #"
6671   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6672    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6674 (define_insn "*mov<mode>_softfloat32"
6675   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6676         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6677   "! TARGET_POWERPC64 
6678    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6679        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6680        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6681    && (gpc_reg_operand (operands[0], <MODE>mode)
6682        || gpc_reg_operand (operands[1], <MODE>mode))"
6683   "#"
6684   [(set_attr "type" "store,load,two,*,*,*")
6685    (set_attr "length" "8,8,8,8,12,16")])
6687 ; ld/std require word-aligned displacements -> 'Y' constraint.
6688 ; List Y->r and r->Y before r->r for reload.
6689 (define_insn "*mov<mode>_hardfloat64"
6690   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,o,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6691         (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6692   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6693    && (gpc_reg_operand (operands[0], <MODE>mode)
6694        || gpc_reg_operand (operands[1], <MODE>mode))"
6695   "@
6696    stfd%U0%X0 %1,%0
6697    lfd%U1%X1 %0,%1
6698    fmr %0,%1
6699    lxsd %0,%1
6700    stxsd %1,%0
6701    lxsd%U1x %x0,%y1
6702    stxsd%U0x %x1,%y0
6703    xxlor %x0,%x1,%x1
6704    xxlxor %x0,%x0,%x0
6705    li %0,0
6706    std%U0%X0 %1,%0
6707    ld%U1%X1 %0,%1
6708    mr %0,%1
6709    mt%0 %1
6710    mf%1 %0
6711    nop
6712    mftgpr %0,%1
6713    mffgpr %0,%1
6714    mfvsrd %0,%x1
6715    mtvsrd %x0,%1"
6716   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6717    (set_attr "length" "4")])
6719 (define_insn "*mov<mode>_softfloat64"
6720   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6721         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6722   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6723    && (gpc_reg_operand (operands[0], <MODE>mode)
6724        || gpc_reg_operand (operands[1], <MODE>mode))"
6725   "@
6726    std%U0%X0 %1,%0
6727    ld%U1%X1 %0,%1
6728    mr %0,%1
6729    mt%0 %1
6730    mf%1 %0
6731    #
6732    #
6733    #
6734    nop"
6735   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6736    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6738 (define_expand "mov<mode>"
6739   [(set (match_operand:FMOVE128 0 "general_operand" "")
6740         (match_operand:FMOVE128 1 "any_operand" ""))]
6741   ""
6742   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6744 ;; It's important to list Y->r and r->Y before r->r because otherwise
6745 ;; reload, given m->r, will try to pick r->r and reload it, which
6746 ;; doesn't make progress.
6748 ;; We can't split little endian direct moves of TDmode, because the words are
6749 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6750 ;; problematical.  Don't allow direct move for this case.
6752 (define_insn_and_split "*mov<mode>_64bit_dm"
6753   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6754         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6755   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6756    && FLOAT128_2REG_P (<MODE>mode)
6757    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6758    && (gpc_reg_operand (operands[0], <MODE>mode)
6759        || gpc_reg_operand (operands[1], <MODE>mode))"
6760   "#"
6761   "&& reload_completed"
6762   [(pc)]
6763 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6764   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6766 (define_insn_and_split "*movtd_64bit_nodm"
6767   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6768         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6769   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6770    && (gpc_reg_operand (operands[0], TDmode)
6771        || gpc_reg_operand (operands[1], TDmode))"
6772   "#"
6773   "&& reload_completed"
6774   [(pc)]
6775 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6776   [(set_attr "length" "8,8,8,12,12,8")])
6778 (define_insn_and_split "*mov<mode>_32bit"
6779   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
6780         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
6781   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6782    && (FLOAT128_2REG_P (<MODE>mode)
6783        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6784        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6785    && (gpc_reg_operand (operands[0], <MODE>mode)
6786        || gpc_reg_operand (operands[1], <MODE>mode))"
6787   "#"
6788   "&& reload_completed"
6789   [(pc)]
6790 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6791   [(set_attr "length" "8,8,8,8,20,20,16")])
6793 (define_insn_and_split "*mov<mode>_softfloat"
6794   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6795         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6796   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6797    && (gpc_reg_operand (operands[0], <MODE>mode)
6798        || gpc_reg_operand (operands[1], <MODE>mode))"
6799   "#"
6800   "&& reload_completed"
6801   [(pc)]
6802 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6803   [(set_attr "length" "20,20,16")])
6805 (define_expand "extenddf<mode>2"
6806   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6807         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6808   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6809    && TARGET_LONG_DOUBLE_128"
6811   if (FLOAT128_IEEE_P (<MODE>mode))
6812     rs6000_expand_float128_convert (operands[0], operands[1], false);
6813   else if (TARGET_E500_DOUBLE)
6814     {
6815       gcc_assert (<MODE>mode == TFmode);
6816       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6817     }
6818   else if (TARGET_VSX)
6819     {
6820       if (<MODE>mode == TFmode)
6821         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
6822       else if (<MODE>mode == IFmode)
6823         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
6824       else
6825         gcc_unreachable ();
6826     }
6827    else
6828     {
6829       rtx zero = gen_reg_rtx (DFmode);
6830       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
6832       if (<MODE>mode == TFmode)
6833         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
6834       else if (<MODE>mode == IFmode)
6835         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
6836       else
6837         gcc_unreachable ();
6838     }
6839   DONE;
6842 ;; Allow memory operands for the source to be created by the combiner.
6843 (define_insn_and_split "extenddf<mode>2_fprs"
6844   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
6845         (float_extend:IBM128
6846          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
6847    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
6848   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6849    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6850   "#"
6851   "&& reload_completed"
6852   [(set (match_dup 3) (match_dup 1))
6853    (set (match_dup 4) (match_dup 2))]
6855   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6856   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6858   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6859   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6862 (define_insn_and_split "extenddf<mode>2_vsx"
6863   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
6864         (float_extend:IBM128
6865          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
6866   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
6867   "#"
6868   "&& reload_completed"
6869   [(set (match_dup 2) (match_dup 1))
6870    (set (match_dup 3) (match_dup 4))]
6872   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6873   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6875   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6876   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6877   operands[4] = CONST0_RTX (DFmode);
6880 (define_expand "extendsf<mode>2"
6881   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6882         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
6883   "TARGET_HARD_FLOAT
6884    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6885    && TARGET_LONG_DOUBLE_128"
6887   if (FLOAT128_IEEE_P (<MODE>mode))
6888     rs6000_expand_float128_convert (operands[0], operands[1], false);
6889   else
6890     {
6891       rtx tmp = gen_reg_rtx (DFmode);
6892       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
6893       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
6894     }
6895   DONE;
6898 (define_expand "trunc<mode>df2"
6899   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6900         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6901   "TARGET_HARD_FLOAT
6902    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6903    && TARGET_LONG_DOUBLE_128"
6905   if (FLOAT128_IEEE_P (<MODE>mode))
6906     {
6907       rs6000_expand_float128_convert (operands[0], operands[1], false);
6908       DONE;
6909     }
6912 (define_insn_and_split "trunc<mode>df2_internal1"
6913   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
6914         (float_truncate:DF
6915          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
6916   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
6917    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
6918   "@
6919    #
6920    fmr %0,%1"
6921   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
6922   [(const_int 0)]
6924   emit_note (NOTE_INSN_DELETED);
6925   DONE;
6927   [(set_attr "type" "fp")])
6929 (define_insn "trunc<mode>df2_internal2"
6930   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6931         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
6932   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
6933    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
6934   "fadd %0,%1,%L1"
6935   [(set_attr "type" "fp")
6936    (set_attr "fp_type" "fp_addsub_d")])
6938 (define_expand "trunc<mode>sf2"
6939   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6940         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6941   "TARGET_HARD_FLOAT
6942    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6943    && TARGET_LONG_DOUBLE_128"
6945   if (FLOAT128_IEEE_P (<MODE>mode))
6946     rs6000_expand_float128_convert (operands[0], operands[1], false);
6947   else if (TARGET_E500_DOUBLE)
6948     {
6949       gcc_assert (<MODE>mode == TFmode);
6950       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
6951     }
6952   else if (<MODE>mode == TFmode)
6953     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
6954   else if (<MODE>mode == IFmode)
6955     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
6956   else
6957     gcc_unreachable ();
6958   DONE;
6961 (define_insn_and_split "trunc<mode>sf2_fprs"
6962   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6963         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
6964    (clobber (match_scratch:DF 2 "=d"))]
6965   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
6966    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6967   "#"
6968   "&& reload_completed"
6969   [(set (match_dup 2)
6970         (float_truncate:DF (match_dup 1)))
6971    (set (match_dup 0)
6972         (float_truncate:SF (match_dup 2)))]
6973   "")
6975 (define_expand "floatsi<mode>2"
6976   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6977         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
6978   "TARGET_HARD_FLOAT
6979    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6980    && TARGET_LONG_DOUBLE_128"
6982   if (FLOAT128_IEEE_P (<MODE>mode))
6983     rs6000_expand_float128_convert (operands[0], operands[1], false);
6984   else
6985     {
6986       rtx tmp = gen_reg_rtx (DFmode);
6987       expand_float (tmp, operands[1], false);
6988       if (<MODE>mode == TFmode)
6989         emit_insn (gen_extenddftf2 (operands[0], tmp));
6990       else if (<MODE>mode == IFmode)
6991         emit_insn (gen_extenddfif2 (operands[0], tmp));
6992       else
6993         gcc_unreachable ();
6994     }
6995   DONE;
6998 ; fadd, but rounding towards zero.
6999 ; This is probably not the optimal code sequence.
7000 (define_insn "fix_trunc_helper<mode>"
7001   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7002         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7003                    UNSPEC_FIX_TRUNC_TF))
7004    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7005   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7006    && FLOAT128_IBM_P (<MODE>mode)"
7007   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7008   [(set_attr "type" "fp")
7009    (set_attr "length" "20")])
7011 (define_expand "fix_trunc<mode>si2"
7012   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7013         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7014   "TARGET_HARD_FLOAT
7015    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7017   if (FLOAT128_IEEE_P (<MODE>mode))
7018     rs6000_expand_float128_convert (operands[0], operands[1], false);
7019   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7020     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7021   else if (<MODE>mode == TFmode)
7022     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7023   else if (<MODE>mode == IFmode)
7024     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7025   else
7026     gcc_unreachable ();
7027   DONE;
7030 (define_expand "fix_trunc<mode>si2_fprs"
7031   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7032                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7033               (clobber (match_dup 2))
7034               (clobber (match_dup 3))
7035               (clobber (match_dup 4))
7036               (clobber (match_dup 5))])]
7037   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7039   operands[2] = gen_reg_rtx (DFmode);
7040   operands[3] = gen_reg_rtx (DFmode);
7041   operands[4] = gen_reg_rtx (DImode);
7042   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7045 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7046   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7047         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7048    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7049    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7050    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7051    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7052   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7053   "#"
7054   ""
7055   [(pc)]
7057   rtx lowword;
7058   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7059                                          operands[3]));
7061   gcc_assert (MEM_P (operands[5]));
7062   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7064   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7065   emit_move_insn (operands[5], operands[4]);
7066   emit_move_insn (operands[0], lowword);
7067   DONE;
7070 (define_expand "fix_trunc<mode>di2"
7071   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7072         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7073   "TARGET_FLOAT128"
7075   rs6000_expand_float128_convert (operands[0], operands[1], false);
7076   DONE;
7079 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7080   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7081         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7082   "TARGET_FLOAT128"
7084   rs6000_expand_float128_convert (operands[0], operands[1], true);
7085   DONE;
7088 (define_expand "floatdi<mode>2"
7089   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7090         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7091   "TARGET_FLOAT128"
7093   rs6000_expand_float128_convert (operands[0], operands[1], false);
7094   DONE;
7097 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7098   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7099         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7100   "TARGET_FLOAT128"
7102   rs6000_expand_float128_convert (operands[0], operands[1], true);
7103   DONE;
7106 (define_expand "neg<mode>2"
7107   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7108         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7109   "FLOAT128_IEEE_P (<MODE>mode)
7110    || (FLOAT128_IBM_P (<MODE>mode)
7111        && TARGET_HARD_FLOAT
7112        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7113   "
7115   if (FLOAT128_IEEE_P (<MODE>mode))
7116     {
7117       if (TARGET_FLOAT128_HW)
7118         {
7119           if (<MODE>mode == TFmode)
7120             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7121           else if (<MODE>mode == KFmode)
7122             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7123           else
7124             gcc_unreachable ();
7125         }
7126       else if (TARGET_FLOAT128)
7127         {
7128           if (<MODE>mode == TFmode)
7129             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7130           else if (<MODE>mode == KFmode)
7131             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7132           else
7133             gcc_unreachable ();
7134         }
7135       else
7136         {
7137           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7138           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7139                                                 <MODE>mode, 1,
7140                                                 operands[1], <MODE>mode);
7142           if (target && !rtx_equal_p (target, operands[0]))
7143             emit_move_insn (operands[0], target);
7144         }
7145       DONE;
7146     }
7149 (define_insn "neg<mode>2_internal"
7150   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7151         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7152   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7153   "*
7155   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7156     return \"fneg %L0,%L1\;fneg %0,%1\";
7157   else
7158     return \"fneg %0,%1\;fneg %L0,%L1\";
7160   [(set_attr "type" "fp")
7161    (set_attr "length" "8")])
7163 (define_expand "abs<mode>2"
7164   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7165         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7166   "FLOAT128_IEEE_P (<MODE>mode)
7167    || (FLOAT128_IBM_P (<MODE>mode)
7168        && TARGET_HARD_FLOAT
7169        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7170   "
7172   rtx label;
7174   if (FLOAT128_IEEE_P (<MODE>mode))
7175     {
7176       if (TARGET_FLOAT128_HW)
7177         {
7178           if (<MODE>mode == TFmode)
7179             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7180           else if (<MODE>mode == KFmode)
7181             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7182           else
7183             FAIL;
7184           DONE;
7185         }
7186       else if (TARGET_FLOAT128)
7187         {
7188           if (<MODE>mode == TFmode)
7189             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7190           else if (<MODE>mode == KFmode)
7191             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7192           else
7193             FAIL;
7194           DONE;
7195         }
7196       else
7197         FAIL;
7198     }
7200   label = gen_label_rtx ();
7201   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7202     {
7203       if (flag_finite_math_only && !flag_trapping_math)
7204         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7205       else
7206         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7207     }
7208   else if (<MODE>mode == TFmode)
7209     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7210   else if (<MODE>mode == TFmode)
7211     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7212   else
7213     FAIL;
7214   emit_label (label);
7215   DONE;
7218 (define_expand "abs<mode>2_internal"
7219   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7220         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7221    (set (match_dup 3) (match_dup 5))
7222    (set (match_dup 5) (abs:DF (match_dup 5)))
7223    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7224    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7225                            (label_ref (match_operand 2 "" ""))
7226                            (pc)))
7227    (set (match_dup 6) (neg:DF (match_dup 6)))]
7228   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7229    && TARGET_LONG_DOUBLE_128"
7230   "
7232   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7233   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7234   operands[3] = gen_reg_rtx (DFmode);
7235   operands[4] = gen_reg_rtx (CCFPmode);
7236   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7237   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7241 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7242 ;; register
7244 (define_expand "ieee_128bit_negative_zero"
7245   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7246   "TARGET_FLOAT128"
7248   rtvec v = rtvec_alloc (16);
7249   int i, high;
7251   for (i = 0; i < 16; i++)
7252     RTVEC_ELT (v, i) = const0_rtx;
7254   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7255   RTVEC_ELT (v, high) = GEN_INT (0x80);
7257   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7258   DONE;
7261 ;; IEEE 128-bit negate
7263 ;; We have 2 insns here for negate and absolute value.  The first uses
7264 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7265 ;; insns, and second insn after the first split pass loads up the bit to
7266 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7267 ;; neg/abs to create the constant just once.
7269 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7270   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7271         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7272    (clobber (match_scratch:V16QI 2 "=v"))]
7273   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7274   "#"
7275   "&& 1"
7276   [(parallel [(set (match_dup 0)
7277                    (neg:IEEE128 (match_dup 1)))
7278               (use (match_dup 2))])]
7280   if (GET_CODE (operands[2]) == SCRATCH)
7281     operands[2] = gen_reg_rtx (V16QImode);
7283   operands[3] = gen_reg_rtx (V16QImode);
7284   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7286   [(set_attr "length" "8")
7287    (set_attr "type" "vecsimple")])
7289 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7290   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7291         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7292    (use (match_operand:V16QI 2 "register_operand" "v"))]
7293   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7294   "xxlxor %x0,%x1,%x2"
7295   [(set_attr "type" "vecsimple")])
7297 ;; IEEE 128-bit absolute value
7298 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7299   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7300         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7301    (clobber (match_scratch:V16QI 2 "=v"))]
7302   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7303   "#"
7304   "&& 1"
7305   [(parallel [(set (match_dup 0)
7306                    (abs:IEEE128 (match_dup 1)))
7307               (use (match_dup 2))])]
7309   if (GET_CODE (operands[2]) == SCRATCH)
7310     operands[2] = gen_reg_rtx (V16QImode);
7312   operands[3] = gen_reg_rtx (V16QImode);
7313   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7315   [(set_attr "length" "8")
7316    (set_attr "type" "vecsimple")])
7318 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7319   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7320         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7321    (use (match_operand:V16QI 2 "register_operand" "v"))]
7322   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7323   "xxlandc %x0,%x1,%x2"
7324   [(set_attr "type" "vecsimple")])
7326 ;; IEEE 128-bit negative absolute value
7327 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7328   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7329         (neg:IEEE128
7330          (abs:IEEE128
7331           (match_operand:IEEE128 1 "register_operand" "wa"))))
7332    (clobber (match_scratch:V16QI 2 "=v"))]
7333   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7334   "#"
7335   "&& 1"
7336   [(parallel [(set (match_dup 0)
7337                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7338               (use (match_dup 2))])]
7340   if (GET_CODE (operands[2]) == SCRATCH)
7341     operands[2] = gen_reg_rtx (V16QImode);
7343   operands[3] = gen_reg_rtx (V16QImode);
7344   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7346   [(set_attr "length" "8")
7347    (set_attr "type" "vecsimple")])
7349 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7350   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7351         (neg:IEEE128
7352          (abs:IEEE128
7353           (match_operand:IEEE128 1 "register_operand" "wa"))))
7354    (use (match_operand:V16QI 2 "register_operand" "v"))]
7355   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7356   "xxlor %x0,%x1,%x2"
7357   [(set_attr "type" "vecsimple")])
7359 ;; Float128 conversion functions.  These expand to library function calls.
7360 ;; We use expand to convert from IBM double double to IEEE 128-bit
7361 ;; and trunc for the opposite.
7362 (define_expand "extendiftf2"
7363   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7364         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7365   "TARGET_FLOAT128"
7367   rs6000_expand_float128_convert (operands[0], operands[1], false);
7368   DONE;
7371 (define_expand "extendifkf2"
7372   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7373         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7374   "TARGET_FLOAT128"
7376   rs6000_expand_float128_convert (operands[0], operands[1], false);
7377   DONE;
7380 (define_expand "extendtfkf2"
7381   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7382         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7383   "TARGET_FLOAT128"
7385   rs6000_expand_float128_convert (operands[0], operands[1], false);
7386   DONE;
7389 (define_expand "trunciftf2"
7390   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7391         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7392   "TARGET_FLOAT128"
7394   rs6000_expand_float128_convert (operands[0], operands[1], false);
7395   DONE;
7398 (define_expand "truncifkf2"
7399   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7400         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7401   "TARGET_FLOAT128"
7403   rs6000_expand_float128_convert (operands[0], operands[1], false);
7404   DONE;
7407 (define_expand "trunckftf2"
7408   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7409         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7410   "TARGET_FLOAT128"
7412   rs6000_expand_float128_convert (operands[0], operands[1], false);
7413   DONE;
7416 (define_expand "trunctfif2"
7417   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7418         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7419   "TARGET_FLOAT128"
7421   rs6000_expand_float128_convert (operands[0], operands[1], false);
7422   DONE;
7426 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7427 ;; must have 3 arguments, and scratch register constraint must be a single
7428 ;; constraint.
7430 ;; Reload patterns to support gpr load/store with misaligned mem.
7431 ;; and multiple gpr load/store at offset >= 0xfffc
7432 (define_expand "reload_<mode>_store"
7433   [(parallel [(match_operand 0 "memory_operand" "=m")
7434               (match_operand 1 "gpc_reg_operand" "r")
7435               (match_operand:GPR 2 "register_operand" "=&b")])]
7436   ""
7438   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7439   DONE;
7442 (define_expand "reload_<mode>_load"
7443   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7444               (match_operand 1 "memory_operand" "m")
7445               (match_operand:GPR 2 "register_operand" "=b")])]
7446   ""
7448   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7449   DONE;
7453 ;; Reload patterns for various types using the vector registers.  We may need
7454 ;; an additional base register to convert the reg+offset addressing to reg+reg
7455 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7456 ;; index register for gpr registers.
7457 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7458   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7459               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7460               (match_operand:P 2 "register_operand" "=b")])]
7461   "<P:tptrsize>"
7463   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7464   DONE;
7467 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7468   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7469               (match_operand:RELOAD 1 "memory_operand" "m")
7470               (match_operand:P 2 "register_operand" "=b")])]
7471   "<P:tptrsize>"
7473   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7474   DONE;
7478 ;; Reload sometimes tries to move the address to a GPR, and can generate
7479 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7480 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7482 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7483   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7484         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7485                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7486                (const_int -16)))]
7487   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7488   "#"
7489   "&& reload_completed"
7490   [(set (match_dup 0)
7491         (plus:P (match_dup 1)
7492                 (match_dup 2)))
7493    (set (match_dup 0)
7494         (and:P (match_dup 0)
7495                (const_int -16)))])
7497 ;; Power8 merge instructions to allow direct move to/from floating point
7498 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7499 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7500 ;; value, since it is allocated in reload and not all of the flow information
7501 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7502 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7503 ;; schedule other instructions between the two instructions.
7505 (define_insn "p8_fmrgow_<mode>"
7506   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7507         (unspec:FMOVE64X [
7508                 (match_operand:DF 1 "register_operand" "d")
7509                 (match_operand:DF 2 "register_operand" "d")]
7510                          UNSPEC_P8V_FMRGOW))]
7511   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7512   "fmrgow %0,%1,%2"
7513   [(set_attr "type" "vecperm")])
7515 (define_insn "p8_mtvsrwz"
7516   [(set (match_operand:DF 0 "register_operand" "=d")
7517         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7518                    UNSPEC_P8V_MTVSRWZ))]
7519   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7520   "mtvsrwz %x0,%1"
7521   [(set_attr "type" "mftgpr")])
7523 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7524   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7525         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7526                          UNSPEC_P8V_RELOAD_FROM_GPR))
7527    (clobber (match_operand:IF 2 "register_operand" "=d"))]
7528   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7529   "#"
7530   "&& reload_completed"
7531   [(const_int 0)]
7533   rtx dest = operands[0];
7534   rtx src = operands[1];
7535   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7536   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7537   rtx gpr_hi_reg = gen_highpart (SImode, src);
7538   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7540   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7541   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7542   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7543   DONE;
7545   [(set_attr "length" "12")
7546    (set_attr "type" "three")])
7548 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7549 (define_insn "p8_mtvsrd_df"
7550   [(set (match_operand:DF 0 "register_operand" "=wa")
7551         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7552                    UNSPEC_P8V_MTVSRD))]
7553   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7554   "mtvsrd %x0,%1"
7555   [(set_attr "type" "mftgpr")])
7557 (define_insn "p8_xxpermdi_<mode>"
7558   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7559         (unspec:FMOVE128_GPR [
7560                 (match_operand:DF 1 "register_operand" "wa")
7561                 (match_operand:DF 2 "register_operand" "wa")]
7562                 UNSPEC_P8V_XXPERMDI))]
7563   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7564   "xxpermdi %x0,%x1,%x2,0"
7565   [(set_attr "type" "vecperm")])
7567 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7568   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7569         (unspec:FMOVE128_GPR
7570          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7571          UNSPEC_P8V_RELOAD_FROM_GPR))
7572    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7573   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7574   "#"
7575   "&& reload_completed"
7576   [(const_int 0)]
7578   rtx dest = operands[0];
7579   rtx src = operands[1];
7580   /* You might think that we could use op0 as one temp and a DF clobber
7581      as op2, but you'd be wrong.  Secondary reload move patterns don't
7582      check for overlap of the clobber and the destination.  */
7583   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7584   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7585   rtx gpr_hi_reg = gen_highpart (DImode, src);
7586   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7588   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7589   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7590   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7591   DONE;
7593   [(set_attr "length" "12")
7594    (set_attr "type" "three")])
7596 (define_split
7597   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7598         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7599   "reload_completed
7600    && (int_reg_operand (operands[0], <MODE>mode)
7601        || int_reg_operand (operands[1], <MODE>mode))
7602    && (!TARGET_DIRECT_MOVE_128
7603        || (!vsx_register_operand (operands[0], <MODE>mode)
7604            && !vsx_register_operand (operands[1], <MODE>mode)))"
7605   [(pc)]
7606 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7608 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7609 ;; type is stored internally as double precision in the VSX registers, we have
7610 ;; to convert it from the vector format.
7611 (define_insn "p8_mtvsrd_sf"
7612   [(set (match_operand:SF 0 "register_operand" "=wa")
7613         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7614                    UNSPEC_P8V_MTVSRD))]
7615   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7616   "mtvsrd %x0,%1"
7617   [(set_attr "type" "mftgpr")])
7619 (define_insn_and_split "reload_vsx_from_gprsf"
7620   [(set (match_operand:SF 0 "register_operand" "=wa")
7621         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7622                    UNSPEC_P8V_RELOAD_FROM_GPR))
7623    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7624   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7625   "#"
7626   "&& reload_completed"
7627   [(const_int 0)]
7629   rtx op0 = operands[0];
7630   rtx op1 = operands[1];
7631   rtx op2 = operands[2];
7632   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7634   /* Move SF value to upper 32-bits for xscvspdpn.  */
7635   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7636   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7637   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7638   DONE;
7640   [(set_attr "length" "8")
7641    (set_attr "type" "two")])
7643 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7644 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7645 ;; and then doing a move of that.
7646 (define_insn "p8_mfvsrd_3_<mode>"
7647   [(set (match_operand:DF 0 "register_operand" "=r")
7648         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7649                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7650   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7651   "mfvsrd %0,%x1"
7652   [(set_attr "type" "mftgpr")])
7654 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7655   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7656         (unspec:FMOVE128_GPR
7657          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7658          UNSPEC_P8V_RELOAD_FROM_VSX))
7659    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7660   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7661   "#"
7662   "&& reload_completed"
7663   [(const_int 0)]
7665   rtx dest = operands[0];
7666   rtx src = operands[1];
7667   rtx tmp = operands[2];
7668   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7669   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7671   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7672   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7673   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7674   DONE;
7676   [(set_attr "length" "12")
7677    (set_attr "type" "three")])
7679 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7680 ;; type is stored internally as double precision, we have to convert it to the
7681 ;; vector format.
7683 (define_insn_and_split "reload_gpr_from_vsxsf"
7684   [(set (match_operand:SF 0 "register_operand" "=r")
7685         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7686                    UNSPEC_P8V_RELOAD_FROM_VSX))
7687    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7688   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7689   "#"
7690   "&& reload_completed"
7691   [(const_int 0)]
7693   rtx op0 = operands[0];
7694   rtx op1 = operands[1];
7695   rtx op2 = operands[2];
7696   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7698   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7699   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7700   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7701   DONE;
7703   [(set_attr "length" "12")
7704    (set_attr "type" "three")])
7706 (define_insn "p8_mfvsrd_4_disf"
7707   [(set (match_operand:DI 0 "register_operand" "=r")
7708         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7709                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7710   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7711   "mfvsrd %0,%x1"
7712   [(set_attr "type" "mftgpr")])
7715 ;; Next come the multi-word integer load and store and the load and store
7716 ;; multiple insns.
7718 ;; List r->r after r->Y, otherwise reload will try to reload a
7719 ;; non-offsettable address by using r->r which won't make progress.
7720 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7721 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7722 (define_insn "*movdi_internal32"
7723   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7724         (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7725   "! TARGET_POWERPC64
7726    && (gpc_reg_operand (operands[0], DImode)
7727        || gpc_reg_operand (operands[1], DImode))"
7728   "@
7729    #
7730    #
7731    #
7732    stfd%U0%X0 %1,%0
7733    lfd%U1%X1 %0,%1
7734    fmr %0,%1
7735    #"
7736   [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7738 (define_split
7739   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7740         (match_operand:DI 1 "const_int_operand" ""))]
7741   "! TARGET_POWERPC64 && reload_completed
7742    && gpr_or_gpr_p (operands[0], operands[1])
7743    && !direct_move_p (operands[0], operands[1])"
7744   [(set (match_dup 2) (match_dup 4))
7745    (set (match_dup 3) (match_dup 1))]
7746   "
7748   HOST_WIDE_INT value = INTVAL (operands[1]);
7749   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7750                                        DImode);
7751   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7752                                        DImode);
7753   operands[4] = GEN_INT (value >> 32);
7754   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7757 (define_split
7758   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7759         (match_operand:DIFD 1 "input_operand" ""))]
7760   "reload_completed && !TARGET_POWERPC64
7761    && gpr_or_gpr_p (operands[0], operands[1])
7762    && !direct_move_p (operands[0], operands[1])"
7763   [(pc)]
7764 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7766 (define_insn "*movdi_internal64"
7767   [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7768         (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7769   "TARGET_POWERPC64
7770    && (gpc_reg_operand (operands[0], DImode)
7771        || gpc_reg_operand (operands[1], DImode))"
7772   "@
7773    std%U0%X0 %1,%0
7774    ld%U1%X1 %0,%1
7775    mr %0,%1
7776    li %0,%1
7777    lis %0,%v1
7778    #
7779    stfd%U0%X0 %1,%0
7780    lfd%U1%X1 %0,%1
7781    fmr %0,%1
7782    mf%1 %0
7783    mt%0 %1
7784    nop
7785    mftgpr %0,%1
7786    mffgpr %0,%1
7787    mfvsrd %0,%x1
7788    mtvsrd %x0,%1
7789    xxlxor %x0,%x0,%x0"
7790   [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7791    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7793 ; Some DImode loads are best done as a load of -1 followed by a mask
7794 ; instruction.
7795 (define_split
7796   [(set (match_operand:DI 0 "gpc_reg_operand")
7797         (match_operand:DI 1 "const_int_operand"))]
7798   "TARGET_POWERPC64
7799    && num_insns_constant (operands[1], DImode) > 1
7800    && rs6000_is_valid_and_mask (operands[1], DImode)"
7801   [(set (match_dup 0)
7802         (const_int -1))
7803    (set (match_dup 0)
7804         (and:DI (match_dup 0)
7805                 (match_dup 1)))]
7806   "")
7808 ;; Split a load of a large constant into the appropriate five-instruction
7809 ;; sequence.  Handle anything in a constant number of insns.
7810 ;; When non-easy constants can go in the TOC, this should use
7811 ;; easy_fp_constant predicate.
7812 (define_split
7813   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7814         (match_operand:DI 1 "const_int_operand" ""))]
7815   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7816   [(set (match_dup 0) (match_dup 2))
7817    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7818   "
7820   if (rs6000_emit_set_const (operands[0], operands[1]))
7821     DONE;
7822   else
7823     FAIL;
7826 (define_split
7827   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7828         (match_operand:DI 1 "const_scalar_int_operand" ""))]
7829   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7830   [(set (match_dup 0) (match_dup 2))
7831    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7832   "
7834   if (rs6000_emit_set_const (operands[0], operands[1]))
7835     DONE;
7836   else
7837     FAIL;
7840 ;; TImode/PTImode is similar, except that we usually want to compute the
7841 ;; address into a register and use lsi/stsi (the exception is during reload).
7843 (define_insn "*mov<mode>_string"
7844   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7845         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7846   "! TARGET_POWERPC64
7847    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7848    && (gpc_reg_operand (operands[0], <MODE>mode)
7849        || gpc_reg_operand (operands[1], <MODE>mode))"
7850   "*
7852   switch (which_alternative)
7853     {
7854     default:
7855       gcc_unreachable ();
7856     case 0:
7857       if (TARGET_STRING)
7858         return \"stswi %1,%P0,16\";
7859     case 1:
7860       return \"#\";
7861     case 2:
7862       /* If the address is not used in the output, we can use lsi.  Otherwise,
7863          fall through to generating four loads.  */
7864       if (TARGET_STRING
7865           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7866         return \"lswi %0,%P1,16\";
7867       /* ... fall through ...  */
7868     case 3:
7869     case 4:
7870     case 5:
7871       return \"#\";
7872     }
7874   [(set_attr "type" "store,store,load,load,*,*")
7875    (set_attr "update" "yes")
7876    (set_attr "indexed" "yes")
7877    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7878                                           (const_string "always")
7879                                           (const_string "conditional")))])
7881 (define_insn "*mov<mode>_ppc64"
7882   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7883         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7884   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7885    && (gpc_reg_operand (operands[0], <MODE>mode)
7886        || gpc_reg_operand (operands[1], <MODE>mode)))"
7888   return rs6000_output_move_128bit (operands);
7890   [(set_attr "type" "store,store,load,load,*,*")
7891    (set_attr "length" "8")])
7893 (define_split
7894   [(set (match_operand:TI2 0 "int_reg_operand" "")
7895         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7896   "TARGET_POWERPC64
7897    && (VECTOR_MEM_NONE_P (<MODE>mode)
7898        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7899   [(set (match_dup 2) (match_dup 4))
7900    (set (match_dup 3) (match_dup 5))]
7901   "
7903   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7904                                        <MODE>mode);
7905   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7906                                        <MODE>mode);
7907   if (CONST_WIDE_INT_P (operands[1]))
7908     {
7909       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7910       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7911     }
7912   else if (CONST_INT_P (operands[1]))
7913     {
7914       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7915       operands[5] = operands[1];
7916     }
7917   else
7918     FAIL;
7921 (define_split
7922   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7923         (match_operand:TI2 1 "input_operand" ""))]
7924   "reload_completed
7925    && gpr_or_gpr_p (operands[0], operands[1])
7926    && !direct_move_p (operands[0], operands[1])
7927    && !quad_load_store_p (operands[0], operands[1])"
7928   [(pc)]
7929 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7931 (define_expand "load_multiple"
7932   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7933                           (match_operand:SI 1 "" ""))
7934                      (use (match_operand:SI 2 "" ""))])]
7935   "TARGET_STRING && !TARGET_POWERPC64"
7936   "
7938   int regno;
7939   int count;
7940   rtx op1;
7941   int i;
7943   /* Support only loading a constant number of fixed-point registers from
7944      memory and only bother with this if more than two; the machine
7945      doesn't support more than eight.  */
7946   if (GET_CODE (operands[2]) != CONST_INT
7947       || INTVAL (operands[2]) <= 2
7948       || INTVAL (operands[2]) > 8
7949       || GET_CODE (operands[1]) != MEM
7950       || GET_CODE (operands[0]) != REG
7951       || REGNO (operands[0]) >= 32)
7952     FAIL;
7954   count = INTVAL (operands[2]);
7955   regno = REGNO (operands[0]);
7957   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7958   op1 = replace_equiv_address (operands[1],
7959                                force_reg (SImode, XEXP (operands[1], 0)));
7961   for (i = 0; i < count; i++)
7962     XVECEXP (operands[3], 0, i)
7963       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7964                      adjust_address_nv (op1, SImode, i * 4));
7967 (define_insn "*ldmsi8"
7968   [(match_parallel 0 "load_multiple_operation"
7969     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7970           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7971      (set (match_operand:SI 3 "gpc_reg_operand" "")
7972           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7973      (set (match_operand:SI 4 "gpc_reg_operand" "")
7974           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7975      (set (match_operand:SI 5 "gpc_reg_operand" "")
7976           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7977      (set (match_operand:SI 6 "gpc_reg_operand" "")
7978           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7979      (set (match_operand:SI 7 "gpc_reg_operand" "")
7980           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7981      (set (match_operand:SI 8 "gpc_reg_operand" "")
7982           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7983      (set (match_operand:SI 9 "gpc_reg_operand" "")
7984           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7985   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7986   "*
7987 { return rs6000_output_load_multiple (operands); }"
7988   [(set_attr "type" "load")
7989    (set_attr "update" "yes")
7990    (set_attr "indexed" "yes")
7991    (set_attr "length" "32")])
7993 (define_insn "*ldmsi7"
7994   [(match_parallel 0 "load_multiple_operation"
7995     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7996           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7997      (set (match_operand:SI 3 "gpc_reg_operand" "")
7998           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7999      (set (match_operand:SI 4 "gpc_reg_operand" "")
8000           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8001      (set (match_operand:SI 5 "gpc_reg_operand" "")
8002           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8003      (set (match_operand:SI 6 "gpc_reg_operand" "")
8004           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8005      (set (match_operand:SI 7 "gpc_reg_operand" "")
8006           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8007      (set (match_operand:SI 8 "gpc_reg_operand" "")
8008           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8009   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8010   "*
8011 { return rs6000_output_load_multiple (operands); }"
8012   [(set_attr "type" "load")
8013    (set_attr "update" "yes")
8014    (set_attr "indexed" "yes")
8015    (set_attr "length" "32")])
8017 (define_insn "*ldmsi6"
8018   [(match_parallel 0 "load_multiple_operation"
8019     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8020           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8021      (set (match_operand:SI 3 "gpc_reg_operand" "")
8022           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8023      (set (match_operand:SI 4 "gpc_reg_operand" "")
8024           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8025      (set (match_operand:SI 5 "gpc_reg_operand" "")
8026           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8027      (set (match_operand:SI 6 "gpc_reg_operand" "")
8028           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8029      (set (match_operand:SI 7 "gpc_reg_operand" "")
8030           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8031   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8032   "*
8033 { return rs6000_output_load_multiple (operands); }"
8034   [(set_attr "type" "load")
8035    (set_attr "update" "yes")
8036    (set_attr "indexed" "yes")
8037    (set_attr "length" "32")])
8039 (define_insn "*ldmsi5"
8040   [(match_parallel 0 "load_multiple_operation"
8041     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8042           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8043      (set (match_operand:SI 3 "gpc_reg_operand" "")
8044           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8045      (set (match_operand:SI 4 "gpc_reg_operand" "")
8046           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8047      (set (match_operand:SI 5 "gpc_reg_operand" "")
8048           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8049      (set (match_operand:SI 6 "gpc_reg_operand" "")
8050           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8051   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8052   "*
8053 { return rs6000_output_load_multiple (operands); }"
8054   [(set_attr "type" "load")
8055    (set_attr "update" "yes")
8056    (set_attr "indexed" "yes")
8057    (set_attr "length" "32")])
8059 (define_insn "*ldmsi4"
8060   [(match_parallel 0 "load_multiple_operation"
8061     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8062           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8063      (set (match_operand:SI 3 "gpc_reg_operand" "")
8064           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8065      (set (match_operand:SI 4 "gpc_reg_operand" "")
8066           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8067      (set (match_operand:SI 5 "gpc_reg_operand" "")
8068           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8069   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8070   "*
8071 { return rs6000_output_load_multiple (operands); }"
8072   [(set_attr "type" "load")
8073    (set_attr "update" "yes")
8074    (set_attr "indexed" "yes")
8075    (set_attr "length" "32")])
8077 (define_insn "*ldmsi3"
8078   [(match_parallel 0 "load_multiple_operation"
8079     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8080           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8081      (set (match_operand:SI 3 "gpc_reg_operand" "")
8082           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8083      (set (match_operand:SI 4 "gpc_reg_operand" "")
8084           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8085   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8086   "*
8087 { return rs6000_output_load_multiple (operands); }"
8088   [(set_attr "type" "load")
8089    (set_attr "update" "yes")
8090    (set_attr "indexed" "yes")
8091    (set_attr "length" "32")])
8093 (define_expand "store_multiple"
8094   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8095                           (match_operand:SI 1 "" ""))
8096                      (clobber (scratch:SI))
8097                      (use (match_operand:SI 2 "" ""))])]
8098   "TARGET_STRING && !TARGET_POWERPC64"
8099   "
8101   int regno;
8102   int count;
8103   rtx to;
8104   rtx op0;
8105   int i;
8107   /* Support only storing a constant number of fixed-point registers to
8108      memory and only bother with this if more than two; the machine
8109      doesn't support more than eight.  */
8110   if (GET_CODE (operands[2]) != CONST_INT
8111       || INTVAL (operands[2]) <= 2
8112       || INTVAL (operands[2]) > 8
8113       || GET_CODE (operands[0]) != MEM
8114       || GET_CODE (operands[1]) != REG
8115       || REGNO (operands[1]) >= 32)
8116     FAIL;
8118   count = INTVAL (operands[2]);
8119   regno = REGNO (operands[1]);
8121   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8122   to = force_reg (SImode, XEXP (operands[0], 0));
8123   op0 = replace_equiv_address (operands[0], to);
8125   XVECEXP (operands[3], 0, 0)
8126     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8127   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8128                                                  gen_rtx_SCRATCH (SImode));
8130   for (i = 1; i < count; i++)
8131     XVECEXP (operands[3], 0, i + 1)
8132       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8133                      gen_rtx_REG (SImode, regno + i));
8136 (define_insn "*stmsi8"
8137   [(match_parallel 0 "store_multiple_operation"
8138     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8139           (match_operand:SI 2 "gpc_reg_operand" "r"))
8140      (clobber (match_scratch:SI 3 "=X"))
8141      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8142           (match_operand:SI 4 "gpc_reg_operand" "r"))
8143      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8144           (match_operand:SI 5 "gpc_reg_operand" "r"))
8145      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8146           (match_operand:SI 6 "gpc_reg_operand" "r"))
8147      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8148           (match_operand:SI 7 "gpc_reg_operand" "r"))
8149      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8150           (match_operand:SI 8 "gpc_reg_operand" "r"))
8151      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8152           (match_operand:SI 9 "gpc_reg_operand" "r"))
8153      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8154           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8155   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8156   "stswi %2,%1,%O0"
8157   [(set_attr "type" "store")
8158    (set_attr "update" "yes")
8159    (set_attr "indexed" "yes")
8160    (set_attr "cell_micro" "always")])
8162 (define_insn "*stmsi7"
8163   [(match_parallel 0 "store_multiple_operation"
8164     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8165           (match_operand:SI 2 "gpc_reg_operand" "r"))
8166      (clobber (match_scratch:SI 3 "=X"))
8167      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8168           (match_operand:SI 4 "gpc_reg_operand" "r"))
8169      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8170           (match_operand:SI 5 "gpc_reg_operand" "r"))
8171      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8172           (match_operand:SI 6 "gpc_reg_operand" "r"))
8173      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8174           (match_operand:SI 7 "gpc_reg_operand" "r"))
8175      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8176           (match_operand:SI 8 "gpc_reg_operand" "r"))
8177      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8178           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8179   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8180   "stswi %2,%1,%O0"
8181   [(set_attr "type" "store")
8182    (set_attr "update" "yes")
8183    (set_attr "indexed" "yes")
8184    (set_attr "cell_micro" "always")])
8186 (define_insn "*stmsi6"
8187   [(match_parallel 0 "store_multiple_operation"
8188     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8189           (match_operand:SI 2 "gpc_reg_operand" "r"))
8190      (clobber (match_scratch:SI 3 "=X"))
8191      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8192           (match_operand:SI 4 "gpc_reg_operand" "r"))
8193      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8194           (match_operand:SI 5 "gpc_reg_operand" "r"))
8195      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8196           (match_operand:SI 6 "gpc_reg_operand" "r"))
8197      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8198           (match_operand:SI 7 "gpc_reg_operand" "r"))
8199      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8200           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8201   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8202   "stswi %2,%1,%O0"
8203   [(set_attr "type" "store")
8204    (set_attr "update" "yes")
8205    (set_attr "indexed" "yes")
8206    (set_attr "cell_micro" "always")])
8208 (define_insn "*stmsi5"
8209   [(match_parallel 0 "store_multiple_operation"
8210     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8211           (match_operand:SI 2 "gpc_reg_operand" "r"))
8212      (clobber (match_scratch:SI 3 "=X"))
8213      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8214           (match_operand:SI 4 "gpc_reg_operand" "r"))
8215      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8216           (match_operand:SI 5 "gpc_reg_operand" "r"))
8217      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8218           (match_operand:SI 6 "gpc_reg_operand" "r"))
8219      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8220           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8221   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8222   "stswi %2,%1,%O0"
8223   [(set_attr "type" "store")
8224    (set_attr "update" "yes")
8225    (set_attr "indexed" "yes")
8226    (set_attr "cell_micro" "always")])
8228 (define_insn "*stmsi4"
8229   [(match_parallel 0 "store_multiple_operation"
8230     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8231           (match_operand:SI 2 "gpc_reg_operand" "r"))
8232      (clobber (match_scratch:SI 3 "=X"))
8233      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8234           (match_operand:SI 4 "gpc_reg_operand" "r"))
8235      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8236           (match_operand:SI 5 "gpc_reg_operand" "r"))
8237      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8238           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8239   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8240   "stswi %2,%1,%O0"
8241   [(set_attr "type" "store")
8242    (set_attr "update" "yes")
8243    (set_attr "indexed" "yes")
8244    (set_attr "cell_micro" "always")])
8246 (define_insn "*stmsi3"
8247   [(match_parallel 0 "store_multiple_operation"
8248     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8249           (match_operand:SI 2 "gpc_reg_operand" "r"))
8250      (clobber (match_scratch:SI 3 "=X"))
8251      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8252           (match_operand:SI 4 "gpc_reg_operand" "r"))
8253      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8254           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8255   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8256   "stswi %2,%1,%O0"
8257   [(set_attr "type" "store")
8258    (set_attr "update" "yes")
8259    (set_attr "indexed" "yes")
8260    (set_attr "cell_micro" "always")])
8262 (define_expand "setmemsi"
8263   [(parallel [(set (match_operand:BLK 0 "" "")
8264                    (match_operand 2 "const_int_operand" ""))
8265               (use (match_operand:SI 1 "" ""))
8266               (use (match_operand:SI 3 "" ""))])]
8267   ""
8268   "
8270   /* If value to set is not zero, use the library routine.  */
8271   if (operands[2] != const0_rtx)
8272     FAIL;
8274   if (expand_block_clear (operands))
8275     DONE;
8276   else
8277     FAIL;
8280 ;; String/block move insn.
8281 ;; Argument 0 is the destination
8282 ;; Argument 1 is the source
8283 ;; Argument 2 is the length
8284 ;; Argument 3 is the alignment
8286 (define_expand "movmemsi"
8287   [(parallel [(set (match_operand:BLK 0 "" "")
8288                    (match_operand:BLK 1 "" ""))
8289               (use (match_operand:SI 2 "" ""))
8290               (use (match_operand:SI 3 "" ""))])]
8291   ""
8292   "
8294   if (expand_block_move (operands))
8295     DONE;
8296   else
8297     FAIL;
8300 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8301 ;; register allocator doesn't have a clue about allocating 8 word registers.
8302 ;; rD/rS = r5 is preferred, efficient form.
8303 (define_expand "movmemsi_8reg"
8304   [(parallel [(set (match_operand 0 "" "")
8305                    (match_operand 1 "" ""))
8306               (use (match_operand 2 "" ""))
8307               (use (match_operand 3 "" ""))
8308               (clobber (reg:SI  5))
8309               (clobber (reg:SI  6))
8310               (clobber (reg:SI  7))
8311               (clobber (reg:SI  8))
8312               (clobber (reg:SI  9))
8313               (clobber (reg:SI 10))
8314               (clobber (reg:SI 11))
8315               (clobber (reg:SI 12))
8316               (clobber (match_scratch:SI 4 ""))])]
8317   "TARGET_STRING"
8318   "")
8320 (define_insn ""
8321   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8322         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8323    (use (match_operand:SI 2 "immediate_operand" "i"))
8324    (use (match_operand:SI 3 "immediate_operand" "i"))
8325    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8326    (clobber (reg:SI  6))
8327    (clobber (reg:SI  7))
8328    (clobber (reg:SI  8))
8329    (clobber (reg:SI  9))
8330    (clobber (reg:SI 10))
8331    (clobber (reg:SI 11))
8332    (clobber (reg:SI 12))
8333    (clobber (match_scratch:SI 5 "=X"))]
8334   "TARGET_STRING
8335    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8336        || INTVAL (operands[2]) == 0)
8337    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8338    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8339    && REGNO (operands[4]) == 5"
8340   "lswi %4,%1,%2\;stswi %4,%0,%2"
8341   [(set_attr "type" "store")
8342    (set_attr "update" "yes")
8343    (set_attr "indexed" "yes")
8344    (set_attr "cell_micro" "always")
8345    (set_attr "length" "8")])
8347 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8348 ;; register allocator doesn't have a clue about allocating 6 word registers.
8349 ;; rD/rS = r5 is preferred, efficient form.
8350 (define_expand "movmemsi_6reg"
8351   [(parallel [(set (match_operand 0 "" "")
8352                    (match_operand 1 "" ""))
8353               (use (match_operand 2 "" ""))
8354               (use (match_operand 3 "" ""))
8355               (clobber (reg:SI  5))
8356               (clobber (reg:SI  6))
8357               (clobber (reg:SI  7))
8358               (clobber (reg:SI  8))
8359               (clobber (reg:SI  9))
8360               (clobber (reg:SI 10))
8361               (clobber (match_scratch:SI 4 ""))])]
8362   "TARGET_STRING"
8363   "")
8365 (define_insn ""
8366   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8367         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8368    (use (match_operand:SI 2 "immediate_operand" "i"))
8369    (use (match_operand:SI 3 "immediate_operand" "i"))
8370    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8371    (clobber (reg:SI  6))
8372    (clobber (reg:SI  7))
8373    (clobber (reg:SI  8))
8374    (clobber (reg:SI  9))
8375    (clobber (reg:SI 10))
8376    (clobber (match_scratch:SI 5 "=X"))]
8377   "TARGET_STRING
8378    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8379    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8380    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8381    && REGNO (operands[4]) == 5"
8382   "lswi %4,%1,%2\;stswi %4,%0,%2"
8383   [(set_attr "type" "store")
8384    (set_attr "update" "yes")
8385    (set_attr "indexed" "yes")
8386    (set_attr "cell_micro" "always")
8387    (set_attr "length" "8")])
8389 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8390 ;; problems with TImode.
8391 ;; rD/rS = r5 is preferred, efficient form.
8392 (define_expand "movmemsi_4reg"
8393   [(parallel [(set (match_operand 0 "" "")
8394                    (match_operand 1 "" ""))
8395               (use (match_operand 2 "" ""))
8396               (use (match_operand 3 "" ""))
8397               (clobber (reg:SI 5))
8398               (clobber (reg:SI 6))
8399               (clobber (reg:SI 7))
8400               (clobber (reg:SI 8))
8401               (clobber (match_scratch:SI 4 ""))])]
8402   "TARGET_STRING"
8403   "")
8405 (define_insn ""
8406   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8407         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8408    (use (match_operand:SI 2 "immediate_operand" "i"))
8409    (use (match_operand:SI 3 "immediate_operand" "i"))
8410    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8411    (clobber (reg:SI 6))
8412    (clobber (reg:SI 7))
8413    (clobber (reg:SI 8))
8414    (clobber (match_scratch:SI 5 "=X"))]
8415   "TARGET_STRING
8416    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8417    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8418    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8419    && REGNO (operands[4]) == 5"
8420   "lswi %4,%1,%2\;stswi %4,%0,%2"
8421   [(set_attr "type" "store")
8422    (set_attr "update" "yes")
8423    (set_attr "indexed" "yes")
8424    (set_attr "cell_micro" "always")
8425    (set_attr "length" "8")])
8427 ;; Move up to 8 bytes at a time.
8428 (define_expand "movmemsi_2reg"
8429   [(parallel [(set (match_operand 0 "" "")
8430                    (match_operand 1 "" ""))
8431               (use (match_operand 2 "" ""))
8432               (use (match_operand 3 "" ""))
8433               (clobber (match_scratch:DI 4 ""))
8434               (clobber (match_scratch:SI 5 ""))])]
8435   "TARGET_STRING && ! TARGET_POWERPC64"
8436   "")
8438 (define_insn ""
8439   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8440         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8441    (use (match_operand:SI 2 "immediate_operand" "i"))
8442    (use (match_operand:SI 3 "immediate_operand" "i"))
8443    (clobber (match_scratch:DI 4 "=&r"))
8444    (clobber (match_scratch:SI 5 "=X"))]
8445   "TARGET_STRING && ! TARGET_POWERPC64
8446    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8447   "lswi %4,%1,%2\;stswi %4,%0,%2"
8448   [(set_attr "type" "store")
8449    (set_attr "update" "yes")
8450    (set_attr "indexed" "yes")
8451    (set_attr "cell_micro" "always")
8452    (set_attr "length" "8")])
8454 ;; Move up to 4 bytes at a time.
8455 (define_expand "movmemsi_1reg"
8456   [(parallel [(set (match_operand 0 "" "")
8457                    (match_operand 1 "" ""))
8458               (use (match_operand 2 "" ""))
8459               (use (match_operand 3 "" ""))
8460               (clobber (match_scratch:SI 4 ""))
8461               (clobber (match_scratch:SI 5 ""))])]
8462   "TARGET_STRING"
8463   "")
8465 (define_insn ""
8466   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8467         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8468    (use (match_operand:SI 2 "immediate_operand" "i"))
8469    (use (match_operand:SI 3 "immediate_operand" "i"))
8470    (clobber (match_scratch:SI 4 "=&r"))
8471    (clobber (match_scratch:SI 5 "=X"))]
8472   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8473   "lswi %4,%1,%2\;stswi %4,%0,%2"
8474   [(set_attr "type" "store")
8475    (set_attr "update" "yes")
8476    (set_attr "indexed" "yes")
8477    (set_attr "cell_micro" "always")
8478    (set_attr "length" "8")])
8480 ;; Define insns that do load or store with update.  Some of these we can
8481 ;; get by using pre-decrement or pre-increment, but the hardware can also
8482 ;; do cases where the increment is not the size of the object.
8484 ;; In all these cases, we use operands 0 and 1 for the register being
8485 ;; incremented because those are the operands that local-alloc will
8486 ;; tie and these are the pair most likely to be tieable (and the ones
8487 ;; that will benefit the most).
8489 (define_insn "*movdi_update1"
8490   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8491         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8492                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8493    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8494         (plus:DI (match_dup 1) (match_dup 2)))]
8495   "TARGET_POWERPC64 && TARGET_UPDATE
8496    && (!avoiding_indexed_address_p (DImode)
8497        || !gpc_reg_operand (operands[2], DImode))"
8498   "@
8499    ldux %3,%0,%2
8500    ldu %3,%2(%0)"
8501   [(set_attr "type" "load")
8502    (set_attr "update" "yes")
8503    (set_attr "indexed" "yes,no")])
8505 (define_insn "movdi_<mode>_update"
8506   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8507                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8508         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8509    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8510         (plus:P (match_dup 1) (match_dup 2)))]
8511   "TARGET_POWERPC64 && TARGET_UPDATE
8512    && (!avoiding_indexed_address_p (Pmode)
8513        || !gpc_reg_operand (operands[2], Pmode)
8514        || (REG_P (operands[0])
8515            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8516   "@
8517    stdux %3,%0,%2
8518    stdu %3,%2(%0)"
8519   [(set_attr "type" "store")
8520    (set_attr "update" "yes")
8521    (set_attr "indexed" "yes,no")])
8523 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8524 ;; needed for stack allocation, even if the user passes -mno-update.
8525 (define_insn "movdi_<mode>_update_stack"
8526   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8527                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8528         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8529    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8530         (plus:P (match_dup 1) (match_dup 2)))]
8531   "TARGET_POWERPC64"
8532   "@
8533    stdux %3,%0,%2
8534    stdu %3,%2(%0)"
8535   [(set_attr "type" "store")
8536    (set_attr "update" "yes")
8537    (set_attr "indexed" "yes,no")])
8539 (define_insn "*movsi_update1"
8540   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8541         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8542                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8543    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8544         (plus:SI (match_dup 1) (match_dup 2)))]
8545   "TARGET_UPDATE
8546    && (!avoiding_indexed_address_p (SImode)
8547        || !gpc_reg_operand (operands[2], SImode))"
8548   "@
8549    lwzux %3,%0,%2
8550    lwzu %3,%2(%0)"
8551   [(set_attr "type" "load")
8552    (set_attr "update" "yes")
8553    (set_attr "indexed" "yes,no")])
8555 (define_insn "*movsi_update2"
8556   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8557         (sign_extend:DI
8558          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8559                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8560    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8561         (plus:DI (match_dup 1) (match_dup 2)))]
8562   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8563    && !avoiding_indexed_address_p (DImode)"
8564   "lwaux %3,%0,%2"
8565   [(set_attr "type" "load")
8566    (set_attr "sign_extend" "yes")
8567    (set_attr "update" "yes")
8568    (set_attr "indexed" "yes")])
8570 (define_insn "movsi_update"
8571   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8572                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8573         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8574    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8575         (plus:SI (match_dup 1) (match_dup 2)))]
8576   "TARGET_UPDATE
8577    && (!avoiding_indexed_address_p (SImode)
8578        || !gpc_reg_operand (operands[2], SImode)
8579        || (REG_P (operands[0])
8580            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8581   "@
8582    stwux %3,%0,%2
8583    stwu %3,%2(%0)"
8584   [(set_attr "type" "store")
8585    (set_attr "update" "yes")
8586    (set_attr "indexed" "yes,no")])
8588 ;; This is an unconditional pattern; needed for stack allocation, even
8589 ;; if the user passes -mno-update.
8590 (define_insn "movsi_update_stack"
8591   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8592                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8593         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8594    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8595         (plus:SI (match_dup 1) (match_dup 2)))]
8596   ""
8597   "@
8598    stwux %3,%0,%2
8599    stwu %3,%2(%0)"
8600   [(set_attr "type" "store")
8601    (set_attr "update" "yes")
8602    (set_attr "indexed" "yes,no")])
8604 (define_insn "*movhi_update1"
8605   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8606         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8607                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8608    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8609         (plus:SI (match_dup 1) (match_dup 2)))]
8610   "TARGET_UPDATE
8611    && (!avoiding_indexed_address_p (SImode)
8612        || !gpc_reg_operand (operands[2], SImode))"
8613   "@
8614    lhzux %3,%0,%2
8615    lhzu %3,%2(%0)"
8616   [(set_attr "type" "load")
8617    (set_attr "update" "yes")
8618    (set_attr "indexed" "yes,no")])
8620 (define_insn "*movhi_update2"
8621   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8622         (zero_extend:SI
8623          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8624                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8625    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8626         (plus:SI (match_dup 1) (match_dup 2)))]
8627   "TARGET_UPDATE
8628    && (!avoiding_indexed_address_p (SImode)
8629        || !gpc_reg_operand (operands[2], SImode))"
8630   "@
8631    lhzux %3,%0,%2
8632    lhzu %3,%2(%0)"
8633   [(set_attr "type" "load")
8634    (set_attr "update" "yes")
8635    (set_attr "indexed" "yes,no")])
8637 (define_insn "*movhi_update3"
8638   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8639         (sign_extend:SI
8640          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8641                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8642    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8643         (plus:SI (match_dup 1) (match_dup 2)))]
8644   "TARGET_UPDATE && rs6000_gen_cell_microcode
8645    && (!avoiding_indexed_address_p (SImode)
8646        || !gpc_reg_operand (operands[2], SImode))"
8647   "@
8648    lhaux %3,%0,%2
8649    lhau %3,%2(%0)"
8650   [(set_attr "type" "load")
8651    (set_attr "sign_extend" "yes")
8652    (set_attr "update" "yes")
8653    (set_attr "indexed" "yes,no")])
8655 (define_insn "*movhi_update4"
8656   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8657                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8658         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8659    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8660         (plus:SI (match_dup 1) (match_dup 2)))]
8661   "TARGET_UPDATE
8662    && (!avoiding_indexed_address_p (SImode)
8663        || !gpc_reg_operand (operands[2], SImode))"
8664   "@
8665    sthux %3,%0,%2
8666    sthu %3,%2(%0)"
8667   [(set_attr "type" "store")
8668    (set_attr "update" "yes")
8669    (set_attr "indexed" "yes,no")])
8671 (define_insn "*movqi_update1"
8672   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8673         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8674                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8675    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8676         (plus:SI (match_dup 1) (match_dup 2)))]
8677   "TARGET_UPDATE
8678    && (!avoiding_indexed_address_p (SImode)
8679        || !gpc_reg_operand (operands[2], SImode))"
8680   "@
8681    lbzux %3,%0,%2
8682    lbzu %3,%2(%0)"
8683   [(set_attr "type" "load")
8684    (set_attr "update" "yes")
8685    (set_attr "indexed" "yes,no")])
8687 (define_insn "*movqi_update2"
8688   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8689         (zero_extend:SI
8690          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8691                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8692    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8693         (plus:SI (match_dup 1) (match_dup 2)))]
8694   "TARGET_UPDATE
8695    && (!avoiding_indexed_address_p (SImode)
8696        || !gpc_reg_operand (operands[2], SImode))"
8697   "@
8698    lbzux %3,%0,%2
8699    lbzu %3,%2(%0)"
8700   [(set_attr "type" "load")
8701    (set_attr "update" "yes")
8702    (set_attr "indexed" "yes,no")])
8704 (define_insn "*movqi_update3"
8705   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8706                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8707         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8708    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8709         (plus:SI (match_dup 1) (match_dup 2)))]
8710   "TARGET_UPDATE
8711    && (!avoiding_indexed_address_p (SImode)
8712        || !gpc_reg_operand (operands[2], SImode))"
8713   "@
8714    stbux %3,%0,%2
8715    stbu %3,%2(%0)"
8716   [(set_attr "type" "store")
8717    (set_attr "update" "yes")
8718    (set_attr "indexed" "yes,no")])
8720 (define_insn "*movsf_update1"
8721   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8722         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8723                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8724    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8725         (plus:SI (match_dup 1) (match_dup 2)))]
8726   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8727    && (!avoiding_indexed_address_p (SImode)
8728        || !gpc_reg_operand (operands[2], SImode))"
8729   "@
8730    lfsux %3,%0,%2
8731    lfsu %3,%2(%0)"
8732   [(set_attr "type" "fpload")
8733    (set_attr "update" "yes")
8734    (set_attr "indexed" "yes,no")])
8736 (define_insn "*movsf_update2"
8737   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8738                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8739         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8740    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8741         (plus:SI (match_dup 1) (match_dup 2)))]
8742   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8743    && (!avoiding_indexed_address_p (SImode)
8744        || !gpc_reg_operand (operands[2], SImode))"
8745   "@
8746    stfsux %3,%0,%2
8747    stfsu %3,%2(%0)"
8748   [(set_attr "type" "fpstore")
8749    (set_attr "update" "yes")
8750    (set_attr "indexed" "yes,no")])
8752 (define_insn "*movsf_update3"
8753   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8754         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8755                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8756    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8757         (plus:SI (match_dup 1) (match_dup 2)))]
8758   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8759    && (!avoiding_indexed_address_p (SImode)
8760        || !gpc_reg_operand (operands[2], SImode))"
8761   "@
8762    lwzux %3,%0,%2
8763    lwzu %3,%2(%0)"
8764   [(set_attr "type" "load")
8765    (set_attr "update" "yes")
8766    (set_attr "indexed" "yes,no")])
8768 (define_insn "*movsf_update4"
8769   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8770                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8771         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8772    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8773         (plus:SI (match_dup 1) (match_dup 2)))]
8774   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8775    && (!avoiding_indexed_address_p (SImode)
8776        || !gpc_reg_operand (operands[2], SImode))"
8777   "@
8778    stwux %3,%0,%2
8779    stwu %3,%2(%0)"
8780   [(set_attr "type" "store")
8781    (set_attr "update" "yes")
8782    (set_attr "indexed" "yes,no")])
8784 (define_insn "*movdf_update1"
8785   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8786         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8787                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8788    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8789         (plus:SI (match_dup 1) (match_dup 2)))]
8790   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8791    && (!avoiding_indexed_address_p (SImode)
8792        || !gpc_reg_operand (operands[2], SImode))"
8793   "@
8794    lfdux %3,%0,%2
8795    lfdu %3,%2(%0)"
8796   [(set_attr "type" "fpload")
8797    (set_attr "update" "yes")
8798    (set_attr "indexed" "yes,no")])
8800 (define_insn "*movdf_update2"
8801   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8802                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8803         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8804    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8805         (plus:SI (match_dup 1) (match_dup 2)))]
8806   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8807    && (!avoiding_indexed_address_p (SImode)
8808        || !gpc_reg_operand (operands[2], SImode))"
8809   "@
8810    stfdux %3,%0,%2
8811    stfdu %3,%2(%0)"
8812   [(set_attr "type" "fpstore")
8813    (set_attr "update" "yes")
8814    (set_attr "indexed" "yes,no")])
8817 ;; After inserting conditional returns we can sometimes have
8818 ;; unnecessary register moves.  Unfortunately we cannot have a
8819 ;; modeless peephole here, because some single SImode sets have early
8820 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
8821 ;; sequences, using get_attr_length here will smash the operands
8822 ;; array.  Neither is there an early_cobbler_p predicate.
8823 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8824 ;; Also this optimization interferes with scalars going into
8825 ;; altivec registers (the code does reloading through the FPRs).
8826 (define_peephole2
8827   [(set (match_operand:DF 0 "gpc_reg_operand" "")
8828         (match_operand:DF 1 "any_operand" ""))
8829    (set (match_operand:DF 2 "gpc_reg_operand" "")
8830         (match_dup 0))]
8831   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8832    && !TARGET_UPPER_REGS_DF
8833    && peep2_reg_dead_p (2, operands[0])"
8834   [(set (match_dup 2) (match_dup 1))])
8836 (define_peephole2
8837   [(set (match_operand:SF 0 "gpc_reg_operand" "")
8838         (match_operand:SF 1 "any_operand" ""))
8839    (set (match_operand:SF 2 "gpc_reg_operand" "")
8840         (match_dup 0))]
8841   "!TARGET_UPPER_REGS_SF
8842    && peep2_reg_dead_p (2, operands[0])"
8843   [(set (match_dup 2) (match_dup 1))])
8846 ;; TLS support.
8848 ;; Mode attributes for different ABIs.
8849 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8850 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8851 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8852 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8854 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8855   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8856         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8857               (match_operand 4 "" "g")))
8858    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8859                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8860                    UNSPEC_TLSGD)
8861    (clobber (reg:SI LR_REGNO))]
8862   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8864   if (TARGET_CMODEL != CMODEL_SMALL)
8865     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8866            "bl %z3\;nop";
8867   else
8868     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8870   "&& TARGET_TLS_MARKERS"
8871   [(set (match_dup 0)
8872         (unspec:TLSmode [(match_dup 1)
8873                          (match_dup 2)]
8874                         UNSPEC_TLSGD))
8875    (parallel [(set (match_dup 0)
8876                    (call (mem:TLSmode (match_dup 3))
8877                          (match_dup 4)))
8878               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8879               (clobber (reg:SI LR_REGNO))])]
8880   ""
8881   [(set_attr "type" "two")
8882    (set (attr "length")
8883      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8884                    (const_int 16)
8885                    (const_int 12)))])
8887 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8888   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8889         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8890               (match_operand 4 "" "g")))
8891    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8892                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8893                    UNSPEC_TLSGD)
8894    (clobber (reg:SI LR_REGNO))]
8895   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8897   if (flag_pic)
8898     {
8899       if (TARGET_SECURE_PLT && flag_pic == 2)
8900         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8901       else
8902         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8903     }
8904   else
8905     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8907   "&& TARGET_TLS_MARKERS"
8908   [(set (match_dup 0)
8909         (unspec:TLSmode [(match_dup 1)
8910                          (match_dup 2)]
8911                         UNSPEC_TLSGD))
8912    (parallel [(set (match_dup 0)
8913                    (call (mem:TLSmode (match_dup 3))
8914                          (match_dup 4)))
8915               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8916               (clobber (reg:SI LR_REGNO))])]
8917   ""
8918   [(set_attr "type" "two")
8919    (set_attr "length" "8")])
8921 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8922   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8923         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8924                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8925                         UNSPEC_TLSGD))]
8926   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8927   "addi %0,%1,%2@got@tlsgd"
8928   "&& TARGET_CMODEL != CMODEL_SMALL"
8929   [(set (match_dup 3)
8930         (high:TLSmode
8931             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8932    (set (match_dup 0)
8933         (lo_sum:TLSmode (match_dup 3)
8934             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8935   "
8937   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8939   [(set (attr "length")
8940      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8941                    (const_int 8)
8942                    (const_int 4)))])
8944 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8945   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8946      (high:TLSmode
8947        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8948                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8949                        UNSPEC_TLSGD)))]
8950   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8951   "addis %0,%1,%2@got@tlsgd@ha"
8952   [(set_attr "length" "4")])
8954 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8955   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8956      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8957        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8958                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8959                        UNSPEC_TLSGD)))]
8960   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8961   "addi %0,%1,%2@got@tlsgd@l"
8962   [(set_attr "length" "4")])
8964 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8965   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8966         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8967               (match_operand 2 "" "g")))
8968    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8969                    UNSPEC_TLSGD)
8970    (clobber (reg:SI LR_REGNO))]
8971   "HAVE_AS_TLS && TARGET_TLS_MARKERS
8972    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8973   "bl %z1(%3@tlsgd)\;nop"
8974   [(set_attr "type" "branch")
8975    (set_attr "length" "8")])
8977 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8978   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8979         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8980               (match_operand 2 "" "g")))
8981    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8982                    UNSPEC_TLSGD)
8983    (clobber (reg:SI LR_REGNO))]
8984   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8986   if (flag_pic)
8987     {
8988       if (TARGET_SECURE_PLT && flag_pic == 2)
8989         return "bl %z1+32768(%3@tlsgd)@plt";
8990       return "bl %z1(%3@tlsgd)@plt";
8991     }
8992   return "bl %z1(%3@tlsgd)";
8994   [(set_attr "type" "branch")
8995    (set_attr "length" "4")])
8997 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8998   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8999         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9000               (match_operand 3 "" "g")))
9001    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9002                    UNSPEC_TLSLD)
9003    (clobber (reg:SI LR_REGNO))]
9004   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9006   if (TARGET_CMODEL != CMODEL_SMALL)
9007     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9008            "bl %z2\;nop";
9009   else
9010     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9012   "&& TARGET_TLS_MARKERS"
9013   [(set (match_dup 0)
9014         (unspec:TLSmode [(match_dup 1)]
9015                         UNSPEC_TLSLD))
9016    (parallel [(set (match_dup 0)
9017                    (call (mem:TLSmode (match_dup 2))
9018                          (match_dup 3)))
9019               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9020               (clobber (reg:SI LR_REGNO))])]
9021   ""
9022   [(set_attr "type" "two")
9023    (set (attr "length")
9024      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9025                    (const_int 16)
9026                    (const_int 12)))])
9028 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9029   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9030         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9031               (match_operand 3 "" "g")))
9032    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9033                    UNSPEC_TLSLD)
9034    (clobber (reg:SI LR_REGNO))]
9035   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9037   if (flag_pic)
9038     {
9039       if (TARGET_SECURE_PLT && flag_pic == 2)
9040         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9041       else
9042         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9043     }
9044   else
9045     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9047   "&& TARGET_TLS_MARKERS"
9048   [(set (match_dup 0)
9049         (unspec:TLSmode [(match_dup 1)]
9050                         UNSPEC_TLSLD))
9051    (parallel [(set (match_dup 0)
9052                    (call (mem:TLSmode (match_dup 2))
9053                          (match_dup 3)))
9054               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9055               (clobber (reg:SI LR_REGNO))])]
9056   ""
9057   [(set_attr "length" "8")])
9059 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9060   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9061         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9062                         UNSPEC_TLSLD))]
9063   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9064   "addi %0,%1,%&@got@tlsld"
9065   "&& TARGET_CMODEL != CMODEL_SMALL"
9066   [(set (match_dup 2)
9067         (high:TLSmode
9068             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9069    (set (match_dup 0)
9070         (lo_sum:TLSmode (match_dup 2)
9071             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9072   "
9074   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9076   [(set (attr "length")
9077      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9078                    (const_int 8)
9079                    (const_int 4)))])
9081 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9082   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9083      (high:TLSmode
9084        (unspec:TLSmode [(const_int 0)
9085                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9086                        UNSPEC_TLSLD)))]
9087   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9088   "addis %0,%1,%&@got@tlsld@ha"
9089   [(set_attr "length" "4")])
9091 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9092   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9093      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9094        (unspec:TLSmode [(const_int 0)
9095                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9096                        UNSPEC_TLSLD)))]
9097   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9098   "addi %0,%1,%&@got@tlsld@l"
9099   [(set_attr "length" "4")])
9101 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9102   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9103         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9104               (match_operand 2 "" "g")))
9105    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9106    (clobber (reg:SI LR_REGNO))]
9107   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9108    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9109   "bl %z1(%&@tlsld)\;nop"
9110   [(set_attr "type" "branch")
9111    (set_attr "length" "8")])
9113 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9114   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9115         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9116               (match_operand 2 "" "g")))
9117    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9118    (clobber (reg:SI LR_REGNO))]
9119   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9121   if (flag_pic)
9122     {
9123       if (TARGET_SECURE_PLT && flag_pic == 2)
9124         return "bl %z1+32768(%&@tlsld)@plt";
9125       return "bl %z1(%&@tlsld)@plt";
9126     }
9127   return "bl %z1(%&@tlsld)";
9129   [(set_attr "type" "branch")
9130    (set_attr "length" "4")])
9132 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9133   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9134         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9135                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9136                         UNSPEC_TLSDTPREL))]
9137   "HAVE_AS_TLS"
9138   "addi %0,%1,%2@dtprel")
9140 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9141   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9142         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9143                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9144                         UNSPEC_TLSDTPRELHA))]
9145   "HAVE_AS_TLS"
9146   "addis %0,%1,%2@dtprel@ha")
9148 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9149   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9150         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9151                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9152                         UNSPEC_TLSDTPRELLO))]
9153   "HAVE_AS_TLS"
9154   "addi %0,%1,%2@dtprel@l")
9156 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9157   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9158         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9159                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9160                         UNSPEC_TLSGOTDTPREL))]
9161   "HAVE_AS_TLS"
9162   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9163   "&& TARGET_CMODEL != CMODEL_SMALL"
9164   [(set (match_dup 3)
9165         (high:TLSmode
9166             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9167    (set (match_dup 0)
9168         (lo_sum:TLSmode (match_dup 3)
9169             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9170   "
9172   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9174   [(set (attr "length")
9175      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9176                    (const_int 8)
9177                    (const_int 4)))])
9179 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9180   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9181      (high:TLSmode
9182        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9183                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9184                        UNSPEC_TLSGOTDTPREL)))]
9185   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9186   "addis %0,%1,%2@got@dtprel@ha"
9187   [(set_attr "length" "4")])
9189 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9190   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9191      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9192          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9193                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9194                          UNSPEC_TLSGOTDTPREL)))]
9195   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9196   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9197   [(set_attr "length" "4")])
9199 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9200   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9201         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9202                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9203                         UNSPEC_TLSTPREL))]
9204   "HAVE_AS_TLS"
9205   "addi %0,%1,%2@tprel")
9207 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9208   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9209         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9210                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9211                         UNSPEC_TLSTPRELHA))]
9212   "HAVE_AS_TLS"
9213   "addis %0,%1,%2@tprel@ha")
9215 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9216   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9217         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9218                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9219                         UNSPEC_TLSTPRELLO))]
9220   "HAVE_AS_TLS"
9221   "addi %0,%1,%2@tprel@l")
9223 ;; "b" output constraint here and on tls_tls input to support linker tls
9224 ;; optimization.  The linker may edit the instructions emitted by a
9225 ;; tls_got_tprel/tls_tls pair to addis,addi.
9226 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9227   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9228         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9229                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9230                         UNSPEC_TLSGOTTPREL))]
9231   "HAVE_AS_TLS"
9232   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9233   "&& TARGET_CMODEL != CMODEL_SMALL"
9234   [(set (match_dup 3)
9235         (high:TLSmode
9236             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9237    (set (match_dup 0)
9238         (lo_sum:TLSmode (match_dup 3)
9239             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9240   "
9242   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9244   [(set (attr "length")
9245      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9246                    (const_int 8)
9247                    (const_int 4)))])
9249 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9250   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9251      (high:TLSmode
9252        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9253                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9254                        UNSPEC_TLSGOTTPREL)))]
9255   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9256   "addis %0,%1,%2@got@tprel@ha"
9257   [(set_attr "length" "4")])
9259 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9260   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9261      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9262          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9263                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9264                          UNSPEC_TLSGOTTPREL)))]
9265   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9266   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9267   [(set_attr "length" "4")])
9269 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9270   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9271         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9272                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9273                         UNSPEC_TLSTLS))]
9274   "TARGET_ELF && HAVE_AS_TLS"
9275   "add %0,%1,%2@tls")
9277 (define_expand "tls_get_tpointer"
9278   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9279         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9280   "TARGET_XCOFF && HAVE_AS_TLS"
9281   "
9283   emit_insn (gen_tls_get_tpointer_internal ());
9284   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9285   DONE;
9288 (define_insn "tls_get_tpointer_internal"
9289   [(set (reg:SI 3)
9290         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9291    (clobber (reg:SI LR_REGNO))]
9292   "TARGET_XCOFF && HAVE_AS_TLS"
9293   "bla __get_tpointer")
9295 (define_expand "tls_get_addr<mode>"
9296   [(set (match_operand:P 0 "gpc_reg_operand" "")
9297         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9298                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9299   "TARGET_XCOFF && HAVE_AS_TLS"
9300   "
9302   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9303   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9304   emit_insn (gen_tls_get_addr_internal<mode> ());
9305   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9306   DONE;
9309 (define_insn "tls_get_addr_internal<mode>"
9310   [(set (reg:P 3)
9311         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9312    (clobber (reg:P 0))
9313    (clobber (reg:P 4))
9314    (clobber (reg:P 5))
9315    (clobber (reg:P 11))
9316    (clobber (reg:CC CR0_REGNO))
9317    (clobber (reg:P LR_REGNO))]
9318   "TARGET_XCOFF && HAVE_AS_TLS"
9319   "bla __tls_get_addr")
9321 ;; Next come insns related to the calling sequence.
9323 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9324 ;; We move the back-chain and decrement the stack pointer.
9326 (define_expand "allocate_stack"
9327   [(set (match_operand 0 "gpc_reg_operand" "")
9328         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9329    (set (reg 1)
9330         (minus (reg 1) (match_dup 1)))]
9331   ""
9332   "
9333 { rtx chain = gen_reg_rtx (Pmode);
9334   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9335   rtx neg_op0;
9336   rtx insn, par, set, mem;
9338   emit_move_insn (chain, stack_bot);
9340   /* Check stack bounds if necessary.  */
9341   if (crtl->limit_stack)
9342     {
9343       rtx available;
9344       available = expand_binop (Pmode, sub_optab,
9345                                 stack_pointer_rtx, stack_limit_rtx,
9346                                 NULL_RTX, 1, OPTAB_WIDEN);
9347       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9348     }
9350   if (GET_CODE (operands[1]) != CONST_INT
9351       || INTVAL (operands[1]) < -32767
9352       || INTVAL (operands[1]) > 32768)
9353     {
9354       neg_op0 = gen_reg_rtx (Pmode);
9355       if (TARGET_32BIT)
9356         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9357       else
9358         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9359     }
9360   else
9361     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9363   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9364                                        : gen_movdi_di_update_stack))
9365                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9366                          chain));
9367   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9368      it now and set the alias set/attributes. The above gen_*_update
9369      calls will generate a PARALLEL with the MEM set being the first
9370      operation. */
9371   par = PATTERN (insn);
9372   gcc_assert (GET_CODE (par) == PARALLEL);
9373   set = XVECEXP (par, 0, 0);
9374   gcc_assert (GET_CODE (set) == SET);
9375   mem = SET_DEST (set);
9376   gcc_assert (MEM_P (mem));
9377   MEM_NOTRAP_P (mem) = 1;
9378   set_mem_alias_set (mem, get_frame_alias_set ());
9380   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9381   DONE;
9384 ;; These patterns say how to save and restore the stack pointer.  We need not
9385 ;; save the stack pointer at function level since we are careful to
9386 ;; preserve the backchain.  At block level, we have to restore the backchain
9387 ;; when we restore the stack pointer.
9389 ;; For nonlocal gotos, we must save both the stack pointer and its
9390 ;; backchain and restore both.  Note that in the nonlocal case, the
9391 ;; save area is a memory location.
9393 (define_expand "save_stack_function"
9394   [(match_operand 0 "any_operand" "")
9395    (match_operand 1 "any_operand" "")]
9396   ""
9397   "DONE;")
9399 (define_expand "restore_stack_function"
9400   [(match_operand 0 "any_operand" "")
9401    (match_operand 1 "any_operand" "")]
9402   ""
9403   "DONE;")
9405 ;; Adjust stack pointer (op0) to a new value (op1).
9406 ;; First copy old stack backchain to new location, and ensure that the
9407 ;; scheduler won't reorder the sp assignment before the backchain write.
9408 (define_expand "restore_stack_block"
9409   [(set (match_dup 2) (match_dup 3))
9410    (set (match_dup 4) (match_dup 2))
9411    (match_dup 5)
9412    (set (match_operand 0 "register_operand" "")
9413         (match_operand 1 "register_operand" ""))]
9414   ""
9415   "
9417   rtvec p;
9419   operands[1] = force_reg (Pmode, operands[1]);
9420   operands[2] = gen_reg_rtx (Pmode);
9421   operands[3] = gen_frame_mem (Pmode, operands[0]);
9422   operands[4] = gen_frame_mem (Pmode, operands[1]);
9423   p = rtvec_alloc (1);
9424   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9425                                   const0_rtx);
9426   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9429 (define_expand "save_stack_nonlocal"
9430   [(set (match_dup 3) (match_dup 4))
9431    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9432    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9433   ""
9434   "
9436   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9438   /* Copy the backchain to the first word, sp to the second.  */
9439   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9440   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9441   operands[3] = gen_reg_rtx (Pmode);
9442   operands[4] = gen_frame_mem (Pmode, operands[1]);
9445 (define_expand "restore_stack_nonlocal"
9446   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9447    (set (match_dup 3) (match_dup 4))
9448    (set (match_dup 5) (match_dup 2))
9449    (match_dup 6)
9450    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9451   ""
9452   "
9454   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9455   rtvec p;
9457   /* Restore the backchain from the first word, sp from the second.  */
9458   operands[2] = gen_reg_rtx (Pmode);
9459   operands[3] = gen_reg_rtx (Pmode);
9460   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9461   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9462   operands[5] = gen_frame_mem (Pmode, operands[3]);
9463   p = rtvec_alloc (1);
9464   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9465                                   const0_rtx);
9466   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9469 ;; TOC register handling.
9471 ;; Code to initialize the TOC register...
9473 (define_insn "load_toc_aix_si"
9474   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9475                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9476               (use (reg:SI 2))])]
9477   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9478   "*
9480   char buf[30];
9481   extern int need_toc_init;
9482   need_toc_init = 1;
9483   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9484   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9485   operands[2] = gen_rtx_REG (Pmode, 2);
9486   return \"lwz %0,%1(%2)\";
9488   [(set_attr "type" "load")
9489    (set_attr "update" "no")
9490    (set_attr "indexed" "no")])
9492 (define_insn "load_toc_aix_di"
9493   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9494                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9495               (use (reg:DI 2))])]
9496   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9497   "*
9499   char buf[30];
9500   extern int need_toc_init;
9501   need_toc_init = 1;
9502 #ifdef TARGET_RELOCATABLE
9503   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9504                                !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9505 #else
9506   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9507 #endif
9508   if (TARGET_ELF)
9509     strcat (buf, \"@toc\");
9510   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9511   operands[2] = gen_rtx_REG (Pmode, 2);
9512   return \"ld %0,%1(%2)\";
9514   [(set_attr "type" "load")
9515    (set_attr "update" "no")
9516    (set_attr "indexed" "no")])
9518 (define_insn "load_toc_v4_pic_si"
9519   [(set (reg:SI LR_REGNO)
9520         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9521   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9522   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9523   [(set_attr "type" "branch")
9524    (set_attr "length" "4")])
9526 (define_expand "load_toc_v4_PIC_1"
9527   [(parallel [(set (reg:SI LR_REGNO)
9528                    (match_operand:SI 0 "immediate_operand" "s"))
9529               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9530   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9531    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9532   "")
9534 (define_insn "load_toc_v4_PIC_1_normal"
9535   [(set (reg:SI LR_REGNO)
9536         (match_operand:SI 0 "immediate_operand" "s"))
9537    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9538   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9539    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9540   "bcl 20,31,%0\\n%0:"
9541   [(set_attr "type" "branch")
9542    (set_attr "length" "4")
9543    (set_attr "cannot_copy" "yes")])
9545 (define_insn "load_toc_v4_PIC_1_476"
9546   [(set (reg:SI LR_REGNO)
9547         (match_operand:SI 0 "immediate_operand" "s"))
9548    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9549   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9550    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9551   "*
9553   char name[32];
9554   static char templ[32];
9556   get_ppc476_thunk_name (name);
9557   sprintf (templ, \"bl %s\\n%%0:\", name);
9558   return templ;
9560   [(set_attr "type" "branch")
9561    (set_attr "length" "4")
9562    (set_attr "cannot_copy" "yes")])
9564 (define_expand "load_toc_v4_PIC_1b"
9565   [(parallel [(set (reg:SI LR_REGNO)
9566                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9567                                (label_ref (match_operand 1 "" ""))]
9568                            UNSPEC_TOCPTR))
9569               (match_dup 1)])]
9570   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9571   "")
9573 (define_insn "load_toc_v4_PIC_1b_normal"
9574   [(set (reg:SI LR_REGNO)
9575         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9576                     (label_ref (match_operand 1 "" ""))]
9577                 UNSPEC_TOCPTR))
9578    (match_dup 1)]
9579   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9580   "bcl 20,31,$+8\;.long %0-$"
9581   [(set_attr "type" "branch")
9582    (set_attr "length" "8")])
9584 (define_insn "load_toc_v4_PIC_1b_476"
9585   [(set (reg:SI LR_REGNO)
9586         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9587                     (label_ref (match_operand 1 "" ""))]
9588                 UNSPEC_TOCPTR))
9589    (match_dup 1)]
9590   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9591   "*
9593   char name[32];
9594   static char templ[32];
9596   get_ppc476_thunk_name (name);
9597   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9598   return templ;
9600   [(set_attr "type" "branch")
9601    (set_attr "length" "16")])
9603 (define_insn "load_toc_v4_PIC_2"
9604   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9605         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9606                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9607                              (match_operand:SI 3 "immediate_operand" "s")))))]
9608   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9609   "lwz %0,%2-%3(%1)"
9610   [(set_attr "type" "load")])
9612 (define_insn "load_toc_v4_PIC_3b"
9613   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9614         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9615                  (high:SI
9616                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9617                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9618   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9619   "addis %0,%1,%2-%3@ha")
9621 (define_insn "load_toc_v4_PIC_3c"
9622   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9623         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9624                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9625                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9626   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9627   "addi %0,%1,%2-%3@l")
9629 ;; If the TOC is shared over a translation unit, as happens with all
9630 ;; the kinds of PIC that we support, we need to restore the TOC
9631 ;; pointer only when jumping over units of translation.
9632 ;; On Darwin, we need to reload the picbase.
9634 (define_expand "builtin_setjmp_receiver"
9635   [(use (label_ref (match_operand 0 "" "")))]
9636   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9637    || (TARGET_TOC && TARGET_MINIMAL_TOC)
9638    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9639   "
9641 #if TARGET_MACHO
9642   if (DEFAULT_ABI == ABI_DARWIN)
9643     {
9644       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9645       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9646       rtx tmplabrtx;
9647       char tmplab[20];
9649       crtl->uses_pic_offset_table = 1;
9650       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9651                                   CODE_LABEL_NUMBER (operands[0]));
9652       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9654       emit_insn (gen_load_macho_picbase (tmplabrtx));
9655       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9656       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9657     }
9658   else
9659 #endif
9660     rs6000_emit_load_toc_table (FALSE);
9661   DONE;
9664 ;; Largetoc support
9665 (define_insn "*largetoc_high"
9666   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9667         (high:DI
9668           (unspec [(match_operand:DI 1 "" "")
9669                    (match_operand:DI 2 "gpc_reg_operand" "b")]
9670                   UNSPEC_TOCREL)))]
9671    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9672    "addis %0,%2,%1@toc@ha")
9674 (define_insn "*largetoc_high_aix<mode>"
9675   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9676         (high:P
9677           (unspec [(match_operand:P 1 "" "")
9678                    (match_operand:P 2 "gpc_reg_operand" "b")]
9679                   UNSPEC_TOCREL)))]
9680    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9681    "addis %0,%1@u(%2)")
9683 (define_insn "*largetoc_high_plus"
9684   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9685         (high:DI
9686           (plus:DI
9687             (unspec [(match_operand:DI 1 "" "")
9688                      (match_operand:DI 2 "gpc_reg_operand" "b")]
9689                     UNSPEC_TOCREL)
9690             (match_operand:DI 3 "add_cint_operand" "n"))))]
9691    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9692    "addis %0,%2,%1+%3@toc@ha")
9694 (define_insn "*largetoc_high_plus_aix<mode>"
9695   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9696         (high:P
9697           (plus:P
9698             (unspec [(match_operand:P 1 "" "")
9699                      (match_operand:P 2 "gpc_reg_operand" "b")]
9700                     UNSPEC_TOCREL)
9701             (match_operand:P 3 "add_cint_operand" "n"))))]
9702    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9703    "addis %0,%1+%3@u(%2)")
9705 (define_insn "*largetoc_low"
9706   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9707         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9708                    (match_operand:DI 2 "" "")))]
9709    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9710    "addi %0,%1,%2@l")
9712 (define_insn "*largetoc_low_aix<mode>"
9713   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9714         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9715                    (match_operand:P 2 "" "")))]
9716    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9717    "la %0,%2@l(%1)")
9719 (define_insn_and_split "*tocref<mode>"
9720   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9721         (match_operand:P 1 "small_toc_ref" "R"))]
9722    "TARGET_TOC"
9723    "la %0,%a1"
9724    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9725   [(set (match_dup 0) (high:P (match_dup 1)))
9726    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9728 ;; Elf specific ways of loading addresses for non-PIC code.
9729 ;; The output of this could be r0, but we make a very strong
9730 ;; preference for a base register because it will usually
9731 ;; be needed there.
9732 (define_insn "elf_high"
9733   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9734         (high:SI (match_operand 1 "" "")))]
9735   "TARGET_ELF && ! TARGET_64BIT"
9736   "lis %0,%1@ha")
9738 (define_insn "elf_low"
9739   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9740         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9741                    (match_operand 2 "" "")))]
9742    "TARGET_ELF && ! TARGET_64BIT"
9743    "la %0,%2@l(%1)")
9745 ;; Call and call_value insns
9746 (define_expand "call"
9747   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9748                     (match_operand 1 "" ""))
9749               (use (match_operand 2 "" ""))
9750               (clobber (reg:SI LR_REGNO))])]
9751   ""
9752   "
9754 #if TARGET_MACHO
9755   if (MACHOPIC_INDIRECT)
9756     operands[0] = machopic_indirect_call_target (operands[0]);
9757 #endif
9759   gcc_assert (GET_CODE (operands[0]) == MEM);
9760   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9762   operands[0] = XEXP (operands[0], 0);
9764   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9765     {
9766       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9767       DONE;
9768     }
9770   if (GET_CODE (operands[0]) != SYMBOL_REF
9771       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9772     {
9773       if (INTVAL (operands[2]) & CALL_LONG)
9774         operands[0] = rs6000_longcall_ref (operands[0]);
9776       switch (DEFAULT_ABI)
9777         {
9778         case ABI_V4:
9779         case ABI_DARWIN:
9780           operands[0] = force_reg (Pmode, operands[0]);
9781           break;
9783         default:
9784           gcc_unreachable ();
9785         }
9786     }
9789 (define_expand "call_value"
9790   [(parallel [(set (match_operand 0 "" "")
9791                    (call (mem:SI (match_operand 1 "address_operand" ""))
9792                          (match_operand 2 "" "")))
9793               (use (match_operand 3 "" ""))
9794               (clobber (reg:SI LR_REGNO))])]
9795   ""
9796   "
9798 #if TARGET_MACHO
9799   if (MACHOPIC_INDIRECT)
9800     operands[1] = machopic_indirect_call_target (operands[1]);
9801 #endif
9803   gcc_assert (GET_CODE (operands[1]) == MEM);
9804   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9806   operands[1] = XEXP (operands[1], 0);
9808   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9809     {
9810       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9811       DONE;
9812     }
9814   if (GET_CODE (operands[1]) != SYMBOL_REF
9815       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9816     {
9817       if (INTVAL (operands[3]) & CALL_LONG)
9818         operands[1] = rs6000_longcall_ref (operands[1]);
9820       switch (DEFAULT_ABI)
9821         {
9822         case ABI_V4:
9823         case ABI_DARWIN:
9824           operands[1] = force_reg (Pmode, operands[1]);
9825           break;
9827         default:
9828           gcc_unreachable ();
9829         }
9830     }
9833 ;; Call to function in current module.  No TOC pointer reload needed.
9834 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9835 ;; either the function was not prototyped, or it was prototyped as a
9836 ;; variable argument function.  It is > 0 if FP registers were passed
9837 ;; and < 0 if they were not.
9839 (define_insn "*call_local32"
9840   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9841          (match_operand 1 "" "g,g"))
9842    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9843    (clobber (reg:SI LR_REGNO))]
9844   "(INTVAL (operands[2]) & CALL_LONG) == 0"
9845   "*
9847   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9848     output_asm_insn (\"crxor 6,6,6\", operands);
9850   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9851     output_asm_insn (\"creqv 6,6,6\", operands);
9853   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9855   [(set_attr "type" "branch")
9856    (set_attr "length" "4,8")])
9858 (define_insn "*call_local64"
9859   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9860          (match_operand 1 "" "g,g"))
9861    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9862    (clobber (reg:SI LR_REGNO))]
9863   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9864   "*
9866   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9867     output_asm_insn (\"crxor 6,6,6\", operands);
9869   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9870     output_asm_insn (\"creqv 6,6,6\", operands);
9872   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9874   [(set_attr "type" "branch")
9875    (set_attr "length" "4,8")])
9877 (define_insn "*call_value_local32"
9878   [(set (match_operand 0 "" "")
9879         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9880               (match_operand 2 "" "g,g")))
9881    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9882    (clobber (reg:SI LR_REGNO))]
9883   "(INTVAL (operands[3]) & CALL_LONG) == 0"
9884   "*
9886   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9887     output_asm_insn (\"crxor 6,6,6\", operands);
9889   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9890     output_asm_insn (\"creqv 6,6,6\", operands);
9892   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9894   [(set_attr "type" "branch")
9895    (set_attr "length" "4,8")])
9898 (define_insn "*call_value_local64"
9899   [(set (match_operand 0 "" "")
9900         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9901               (match_operand 2 "" "g,g")))
9902    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9903    (clobber (reg:SI LR_REGNO))]
9904   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9905   "*
9907   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9908     output_asm_insn (\"crxor 6,6,6\", operands);
9910   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9911     output_asm_insn (\"creqv 6,6,6\", operands);
9913   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9915   [(set_attr "type" "branch")
9916    (set_attr "length" "4,8")])
9919 ;; A function pointer under System V is just a normal pointer
9920 ;; operands[0] is the function pointer
9921 ;; operands[1] is the stack size to clean up
9922 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9923 ;; which indicates how to set cr1
9925 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9926   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9927          (match_operand 1 "" "g,g,g,g"))
9928    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9929    (clobber (reg:SI LR_REGNO))]
9930   "DEFAULT_ABI == ABI_V4
9931    || DEFAULT_ABI == ABI_DARWIN"
9933   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9934     output_asm_insn ("crxor 6,6,6", operands);
9936   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9937     output_asm_insn ("creqv 6,6,6", operands);
9939   return "b%T0l";
9941   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9942    (set_attr "length" "4,4,8,8")])
9944 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9945   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9946          (match_operand 1 "" "g,g"))
9947    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9948    (clobber (reg:SI LR_REGNO))]
9949   "(DEFAULT_ABI == ABI_DARWIN
9950    || (DEFAULT_ABI == ABI_V4
9951        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9953   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9954     output_asm_insn ("crxor 6,6,6", operands);
9956   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9957     output_asm_insn ("creqv 6,6,6", operands);
9959 #if TARGET_MACHO
9960   return output_call(insn, operands, 0, 2);
9961 #else
9962   if (DEFAULT_ABI == ABI_V4 && flag_pic)
9963     {
9964       gcc_assert (!TARGET_SECURE_PLT);
9965       return "bl %z0@plt";
9966     }
9967   else
9968     return "bl %z0";
9969 #endif
9971   "DEFAULT_ABI == ABI_V4
9972    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9973    && (INTVAL (operands[2]) & CALL_LONG) == 0"
9974   [(parallel [(call (mem:SI (match_dup 0))
9975                     (match_dup 1))
9976               (use (match_dup 2))
9977               (use (match_dup 3))
9978               (clobber (reg:SI LR_REGNO))])]
9980   operands[3] = pic_offset_table_rtx;
9982   [(set_attr "type" "branch,branch")
9983    (set_attr "length" "4,8")])
9985 (define_insn "*call_nonlocal_sysv_secure<mode>"
9986   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9987          (match_operand 1 "" "g,g"))
9988    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9989    (use (match_operand:SI 3 "register_operand" "r,r"))
9990    (clobber (reg:SI LR_REGNO))]
9991   "(DEFAULT_ABI == ABI_V4
9992     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9993     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9995   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9996     output_asm_insn ("crxor 6,6,6", operands);
9998   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9999     output_asm_insn ("creqv 6,6,6", operands);
10001   if (flag_pic == 2)
10002     /* The magic 32768 offset here and in the other sysv call insns
10003        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10004        See sysv4.h:toc_section.  */
10005     return "bl %z0+32768@plt";
10006   else
10007     return "bl %z0@plt";
10009   [(set_attr "type" "branch,branch")
10010    (set_attr "length" "4,8")])
10012 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10013   [(set (match_operand 0 "" "")
10014         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10015               (match_operand 2 "" "g,g,g,g")))
10016    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10017    (clobber (reg:SI LR_REGNO))]
10018   "DEFAULT_ABI == ABI_V4
10019    || DEFAULT_ABI == ABI_DARWIN"
10021   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10022     output_asm_insn ("crxor 6,6,6", operands);
10024   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10025     output_asm_insn ("creqv 6,6,6", operands);
10027   return "b%T1l";
10029   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10030    (set_attr "length" "4,4,8,8")])
10032 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10033   [(set (match_operand 0 "" "")
10034         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10035               (match_operand 2 "" "g,g")))
10036    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10037    (clobber (reg:SI LR_REGNO))]
10038   "(DEFAULT_ABI == ABI_DARWIN
10039    || (DEFAULT_ABI == ABI_V4
10040        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10042   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10043     output_asm_insn ("crxor 6,6,6", operands);
10045   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10046     output_asm_insn ("creqv 6,6,6", operands);
10048 #if TARGET_MACHO
10049   return output_call(insn, operands, 1, 3);
10050 #else
10051   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10052     {
10053       gcc_assert (!TARGET_SECURE_PLT);
10054       return "bl %z1@plt";
10055     }
10056   else
10057     return "bl %z1";
10058 #endif
10060   "DEFAULT_ABI == ABI_V4
10061    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10062    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10063   [(parallel [(set (match_dup 0)
10064                    (call (mem:SI (match_dup 1))
10065                          (match_dup 2)))
10066               (use (match_dup 3))
10067               (use (match_dup 4))
10068               (clobber (reg:SI LR_REGNO))])]
10070   operands[4] = pic_offset_table_rtx;
10072   [(set_attr "type" "branch,branch")
10073    (set_attr "length" "4,8")])
10075 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10076   [(set (match_operand 0 "" "")
10077         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10078               (match_operand 2 "" "g,g")))
10079    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10080    (use (match_operand:SI 4 "register_operand" "r,r"))
10081    (clobber (reg:SI LR_REGNO))]
10082   "(DEFAULT_ABI == ABI_V4
10083     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10084     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10086   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10087     output_asm_insn ("crxor 6,6,6", operands);
10089   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10090     output_asm_insn ("creqv 6,6,6", operands);
10092   if (flag_pic == 2)
10093     return "bl %z1+32768@plt";
10094   else
10095     return "bl %z1@plt";
10097   [(set_attr "type" "branch,branch")
10098    (set_attr "length" "4,8")])
10101 ;; Call to AIX abi function in the same module.
10103 (define_insn "*call_local_aix<mode>"
10104   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10105          (match_operand 1 "" "g"))
10106    (clobber (reg:P LR_REGNO))]
10107   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10108   "bl %z0"
10109   [(set_attr "type" "branch")
10110    (set_attr "length" "4")])
10112 (define_insn "*call_value_local_aix<mode>"
10113   [(set (match_operand 0 "" "")
10114         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10115               (match_operand 2 "" "g")))
10116    (clobber (reg:P LR_REGNO))]
10117   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10118   "bl %z1"
10119   [(set_attr "type" "branch")
10120    (set_attr "length" "4")])
10122 ;; Call to AIX abi function which may be in another module.
10123 ;; Restore the TOC pointer (r2) after the call.
10125 (define_insn "*call_nonlocal_aix<mode>"
10126   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10127          (match_operand 1 "" "g"))
10128    (clobber (reg:P LR_REGNO))]
10129   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10130   "bl %z0\;nop"
10131   [(set_attr "type" "branch")
10132    (set_attr "length" "8")])
10134 (define_insn "*call_value_nonlocal_aix<mode>"
10135   [(set (match_operand 0 "" "")
10136         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10137               (match_operand 2 "" "g")))
10138    (clobber (reg:P LR_REGNO))]
10139   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10140   "bl %z1\;nop"
10141   [(set_attr "type" "branch")
10142    (set_attr "length" "8")])
10144 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10145 ;; Operand0 is the addresss of the function to call
10146 ;; Operand2 is the location in the function descriptor to load r2 from
10147 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10149 (define_insn "*call_indirect_aix<mode>"
10150   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10151          (match_operand 1 "" "g,g"))
10152    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10153    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10154    (clobber (reg:P LR_REGNO))]
10155   "DEFAULT_ABI == ABI_AIX"
10156   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10157   [(set_attr "type" "jmpreg")
10158    (set_attr "length" "12")])
10160 (define_insn "*call_value_indirect_aix<mode>"
10161   [(set (match_operand 0 "" "")
10162         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10163               (match_operand 2 "" "g,g")))
10164    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10165    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10166    (clobber (reg:P LR_REGNO))]
10167   "DEFAULT_ABI == ABI_AIX"
10168   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10169   [(set_attr "type" "jmpreg")
10170    (set_attr "length" "12")])
10172 ;; Call to indirect functions with the ELFv2 ABI.
10173 ;; Operand0 is the addresss of the function to call
10174 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10176 (define_insn "*call_indirect_elfv2<mode>"
10177   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10178          (match_operand 1 "" "g,g"))
10179    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10180    (clobber (reg:P LR_REGNO))]
10181   "DEFAULT_ABI == ABI_ELFv2"
10182   "b%T0l\;<ptrload> 2,%2(1)"
10183   [(set_attr "type" "jmpreg")
10184    (set_attr "length" "8")])
10186 (define_insn "*call_value_indirect_elfv2<mode>"
10187   [(set (match_operand 0 "" "")
10188         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10189               (match_operand 2 "" "g,g")))
10190    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10191    (clobber (reg:P LR_REGNO))]
10192   "DEFAULT_ABI == ABI_ELFv2"
10193   "b%T1l\;<ptrload> 2,%3(1)"
10194   [(set_attr "type" "jmpreg")
10195    (set_attr "length" "8")])
10198 ;; Call subroutine returning any type.
10199 (define_expand "untyped_call"
10200   [(parallel [(call (match_operand 0 "" "")
10201                     (const_int 0))
10202               (match_operand 1 "" "")
10203               (match_operand 2 "" "")])]
10204   ""
10205   "
10207   int i;
10209   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10211   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10212     {
10213       rtx set = XVECEXP (operands[2], 0, i);
10214       emit_move_insn (SET_DEST (set), SET_SRC (set));
10215     }
10217   /* The optimizer does not know that the call sets the function value
10218      registers we stored in the result block.  We avoid problems by
10219      claiming that all hard registers are used and clobbered at this
10220      point.  */
10221   emit_insn (gen_blockage ());
10223   DONE;
10226 ;; sibling call patterns
10227 (define_expand "sibcall"
10228   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10229                     (match_operand 1 "" ""))
10230               (use (match_operand 2 "" ""))
10231               (use (reg:SI LR_REGNO))
10232               (simple_return)])]
10233   ""
10234   "
10236 #if TARGET_MACHO
10237   if (MACHOPIC_INDIRECT)
10238     operands[0] = machopic_indirect_call_target (operands[0]);
10239 #endif
10241   gcc_assert (GET_CODE (operands[0]) == MEM);
10242   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10244   operands[0] = XEXP (operands[0], 0);
10246   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10247     {
10248       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10249       DONE;
10250     }
10253 (define_expand "sibcall_value"
10254   [(parallel [(set (match_operand 0 "register_operand" "")
10255                 (call (mem:SI (match_operand 1 "address_operand" ""))
10256                       (match_operand 2 "" "")))
10257               (use (match_operand 3 "" ""))
10258               (use (reg:SI LR_REGNO))
10259               (simple_return)])]
10260   ""
10261   "
10263 #if TARGET_MACHO
10264   if (MACHOPIC_INDIRECT)
10265     operands[1] = machopic_indirect_call_target (operands[1]);
10266 #endif
10268   gcc_assert (GET_CODE (operands[1]) == MEM);
10269   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10271   operands[1] = XEXP (operands[1], 0);
10273   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10274     {
10275       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10276       DONE;
10277     }
10280 ;; this and similar patterns must be marked as using LR, otherwise
10281 ;; dataflow will try to delete the store into it.  This is true
10282 ;; even when the actual reg to jump to is in CTR, when LR was
10283 ;; saved and restored around the PIC-setting BCL.
10284 (define_insn "*sibcall_local32"
10285   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10286          (match_operand 1 "" "g,g"))
10287    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10288    (use (reg:SI LR_REGNO))
10289    (simple_return)]
10290   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10291   "*
10293   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10294     output_asm_insn (\"crxor 6,6,6\", operands);
10296   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10297     output_asm_insn (\"creqv 6,6,6\", operands);
10299   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10301   [(set_attr "type" "branch")
10302    (set_attr "length" "4,8")])
10304 (define_insn "*sibcall_local64"
10305   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10306          (match_operand 1 "" "g,g"))
10307    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10308    (use (reg:SI LR_REGNO))
10309    (simple_return)]
10310   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10311   "*
10313   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10314     output_asm_insn (\"crxor 6,6,6\", operands);
10316   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10317     output_asm_insn (\"creqv 6,6,6\", operands);
10319   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10321   [(set_attr "type" "branch")
10322    (set_attr "length" "4,8")])
10324 (define_insn "*sibcall_value_local32"
10325   [(set (match_operand 0 "" "")
10326         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10327               (match_operand 2 "" "g,g")))
10328    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10329    (use (reg:SI LR_REGNO))
10330    (simple_return)]
10331   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10332   "*
10334   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10335     output_asm_insn (\"crxor 6,6,6\", operands);
10337   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10338     output_asm_insn (\"creqv 6,6,6\", operands);
10340   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10342   [(set_attr "type" "branch")
10343    (set_attr "length" "4,8")])
10345 (define_insn "*sibcall_value_local64"
10346   [(set (match_operand 0 "" "")
10347         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10348               (match_operand 2 "" "g,g")))
10349    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10350    (use (reg:SI LR_REGNO))
10351    (simple_return)]
10352   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10353   "*
10355   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10356     output_asm_insn (\"crxor 6,6,6\", operands);
10358   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10359     output_asm_insn (\"creqv 6,6,6\", operands);
10361   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10363   [(set_attr "type" "branch")
10364    (set_attr "length" "4,8")])
10366 (define_insn "*sibcall_nonlocal_sysv<mode>"
10367   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10368          (match_operand 1 "" ""))
10369    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10370    (use (reg:SI LR_REGNO))
10371    (simple_return)]
10372   "(DEFAULT_ABI == ABI_DARWIN
10373     || DEFAULT_ABI == ABI_V4)
10374    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10375   "*
10377   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10378     output_asm_insn (\"crxor 6,6,6\", operands);
10380   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10381     output_asm_insn (\"creqv 6,6,6\", operands);
10383   if (which_alternative >= 2)
10384     return \"b%T0\";
10385   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10386     {
10387       gcc_assert (!TARGET_SECURE_PLT);
10388       return \"b %z0@plt\";
10389     }
10390   else
10391     return \"b %z0\";
10393   [(set_attr "type" "branch")
10394    (set_attr "length" "4,8,4,8")])
10396 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10397   [(set (match_operand 0 "" "")
10398         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10399               (match_operand 2 "" "")))
10400    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10401    (use (reg:SI LR_REGNO))
10402    (simple_return)]
10403   "(DEFAULT_ABI == ABI_DARWIN
10404     || DEFAULT_ABI == ABI_V4)
10405    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10406   "*
10408   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10409     output_asm_insn (\"crxor 6,6,6\", operands);
10411   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10412     output_asm_insn (\"creqv 6,6,6\", operands);
10414   if (which_alternative >= 2)
10415     return \"b%T1\";
10416   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10417     {
10418       gcc_assert (!TARGET_SECURE_PLT);
10419       return \"b %z1@plt\";
10420     }
10421   else
10422     return \"b %z1\";
10424   [(set_attr "type" "branch")
10425    (set_attr "length" "4,8,4,8")])
10427 ;; AIX ABI sibling call patterns.
10429 (define_insn "*sibcall_aix<mode>"
10430   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10431          (match_operand 1 "" "g,g"))
10432    (simple_return)]
10433   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10434   "@
10435    b %z0
10436    b%T0"
10437   [(set_attr "type" "branch")
10438    (set_attr "length" "4")])
10440 (define_insn "*sibcall_value_aix<mode>"
10441   [(set (match_operand 0 "" "")
10442         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10443               (match_operand 2 "" "g,g")))
10444    (simple_return)]
10445   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10446   "@
10447    b %z1
10448    b%T1"
10449   [(set_attr "type" "branch")
10450    (set_attr "length" "4")])
10452 (define_expand "sibcall_epilogue"
10453   [(use (const_int 0))]
10454   ""
10456   if (!TARGET_SCHED_PROLOG)
10457     emit_insn (gen_blockage ());
10458   rs6000_emit_epilogue (TRUE);
10459   DONE;
10462 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10463 ;; all of memory.  This blocks insns from being moved across this point.
10465 (define_insn "blockage"
10466   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10467   ""
10468   "")
10470 (define_expand "probe_stack_address"
10471   [(use (match_operand 0 "address_operand"))]
10472   ""
10474   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10475   MEM_VOLATILE_P (operands[0]) = 1;
10477   if (TARGET_64BIT)
10478     emit_insn (gen_probe_stack_di (operands[0]));
10479   else
10480     emit_insn (gen_probe_stack_si (operands[0]));
10481   DONE;
10484 (define_insn "probe_stack_<mode>"
10485   [(set (match_operand:P 0 "memory_operand" "=m")
10486         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10487   ""
10489   operands[1] = gen_rtx_REG (Pmode, 0);
10490   return "st<wd>%U0%X0 %1,%0";
10492   [(set_attr "type" "store")
10493    (set (attr "update")
10494         (if_then_else (match_operand 0 "update_address_mem")
10495                       (const_string "yes")
10496                       (const_string "no")))
10497    (set (attr "indexed")
10498         (if_then_else (match_operand 0 "indexed_address_mem")
10499                       (const_string "yes")
10500                       (const_string "no")))
10501    (set_attr "length" "4")])
10503 (define_insn "probe_stack_range<P:mode>"
10504   [(set (match_operand:P 0 "register_operand" "=r")
10505         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10506                             (match_operand:P 2 "register_operand" "r")]
10507                            UNSPECV_PROBE_STACK_RANGE))]
10508   ""
10509   "* return output_probe_stack_range (operands[0], operands[2]);"
10510   [(set_attr "type" "three")])
10512 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10513 ;; signed & unsigned, and one type of branch.
10515 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10516 ;; insns, and branches.
10518 (define_expand "cbranch<mode>4"
10519   [(use (match_operator 0 "rs6000_cbranch_operator"
10520          [(match_operand:GPR 1 "gpc_reg_operand" "")
10521           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10522    (use (match_operand 3 ""))]
10523   ""
10524   "
10526   /* Take care of the possibility that operands[2] might be negative but
10527      this might be a logical operation.  That insn doesn't exist.  */
10528   if (GET_CODE (operands[2]) == CONST_INT
10529       && INTVAL (operands[2]) < 0)
10530     {
10531       operands[2] = force_reg (<MODE>mode, operands[2]);
10532       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10533                                     GET_MODE (operands[0]),
10534                                     operands[1], operands[2]);
10535    }
10537   rs6000_emit_cbranch (<MODE>mode, operands);
10538   DONE;
10541 (define_expand "cbranch<mode>4"
10542   [(use (match_operator 0 "rs6000_cbranch_operator"
10543          [(match_operand:FP 1 "gpc_reg_operand" "")
10544           (match_operand:FP 2 "gpc_reg_operand" "")]))
10545    (use (match_operand 3 ""))]
10546   ""
10547   "
10549   rs6000_emit_cbranch (<MODE>mode, operands);
10550   DONE;
10553 (define_expand "cstore<mode>4_signed"
10554   [(use (match_operator 1 "signed_comparison_operator"
10555          [(match_operand:P 2 "gpc_reg_operand")
10556           (match_operand:P 3 "gpc_reg_operand")]))
10557    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10558   ""
10560   enum rtx_code cond_code = GET_CODE (operands[1]);
10562   rtx op0 = operands[0];
10563   rtx op1 = operands[2];
10564   rtx op2 = operands[3];
10566   if (cond_code == GE || cond_code == LT)
10567     {
10568       cond_code = swap_condition (cond_code);
10569       std::swap (op1, op2);
10570     }
10572   rtx tmp1 = gen_reg_rtx (<MODE>mode);
10573   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10574   rtx tmp3 = gen_reg_rtx (<MODE>mode);
10576   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10577   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10578   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10580   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10582   if (cond_code == LE)
10583     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10584   else
10585     {
10586       rtx tmp4 = gen_reg_rtx (<MODE>mode);
10587       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10588       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10589     }
10591   DONE;
10594 (define_expand "cstore<mode>4_unsigned"
10595   [(use (match_operator 1 "unsigned_comparison_operator"
10596          [(match_operand:P 2 "gpc_reg_operand")
10597           (match_operand:P 3 "reg_or_short_operand")]))
10598    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10599   ""
10601   enum rtx_code cond_code = GET_CODE (operands[1]);
10603   rtx op0 = operands[0];
10604   rtx op1 = operands[2];
10605   rtx op2 = operands[3];
10607   if (cond_code == GEU || cond_code == LTU)
10608     {
10609       cond_code = swap_condition (cond_code);
10610       std::swap (op1, op2);
10611     }
10613   if (!gpc_reg_operand (op1, <MODE>mode))
10614     op1 = force_reg (<MODE>mode, op1);
10615   if (!reg_or_short_operand (op2, <MODE>mode))
10616     op2 = force_reg (<MODE>mode, op2);
10618   rtx tmp = gen_reg_rtx (<MODE>mode);
10619   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10621   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10622   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10624   if (cond_code == LEU)
10625     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10626   else
10627     emit_insn (gen_neg<mode>2 (op0, tmp2));
10629   DONE;
10632 (define_expand "cstore_si_as_di"
10633   [(use (match_operator 1 "unsigned_comparison_operator"
10634          [(match_operand:SI 2 "gpc_reg_operand")
10635           (match_operand:SI 3 "reg_or_short_operand")]))
10636    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10637   ""
10639   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10640   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10642   operands[2] = force_reg (SImode, operands[2]);
10643   operands[3] = force_reg (SImode, operands[3]);
10644   rtx op1 = gen_reg_rtx (DImode);
10645   rtx op2 = gen_reg_rtx (DImode);
10646   convert_move (op1, operands[2], uns_flag);
10647   convert_move (op2, operands[3], uns_flag);
10649   if (cond_code == GT || cond_code == LE)
10650     {
10651       cond_code = swap_condition (cond_code);
10652       std::swap (op1, op2);
10653     }
10655   rtx tmp = gen_reg_rtx (DImode);
10656   rtx tmp2 = gen_reg_rtx (DImode);
10657   emit_insn (gen_subdi3 (tmp, op1, op2));
10658   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10660   rtx tmp3;
10661   switch (cond_code)
10662     {
10663     default:
10664       gcc_unreachable ();
10665     case LT:
10666       tmp3 = tmp2;
10667       break;
10668     case GE:
10669       tmp3 = gen_reg_rtx (DImode);
10670       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10671       break;
10672     }
10674   convert_move (operands[0], tmp3, 1);
10676   DONE;
10679 (define_expand "cstore<mode>4_signed_imm"
10680   [(use (match_operator 1 "signed_comparison_operator"
10681          [(match_operand:GPR 2 "gpc_reg_operand")
10682           (match_operand:GPR 3 "immediate_operand")]))
10683    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10684   ""
10686   bool invert = false;
10688   enum rtx_code cond_code = GET_CODE (operands[1]);
10690   rtx op0 = operands[0];
10691   rtx op1 = operands[2];
10692   HOST_WIDE_INT val = INTVAL (operands[3]);
10694   if (cond_code == GE || cond_code == GT)
10695     {
10696       cond_code = reverse_condition (cond_code);
10697       invert = true;
10698     }
10700   if (cond_code == LE)
10701     val++;
10703   rtx tmp = gen_reg_rtx (<MODE>mode);
10704   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10705   rtx x = gen_reg_rtx (<MODE>mode);
10706   if (val < 0)
10707     emit_insn (gen_and<mode>3 (x, op1, tmp));
10708   else
10709     emit_insn (gen_ior<mode>3 (x, op1, tmp));
10711   if (invert)
10712     {
10713       rtx tmp = gen_reg_rtx (<MODE>mode);
10714       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10715       x = tmp;
10716     }
10718   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10719   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10721   DONE;
10724 (define_expand "cstore<mode>4_unsigned_imm"
10725   [(use (match_operator 1 "unsigned_comparison_operator"
10726          [(match_operand:GPR 2 "gpc_reg_operand")
10727           (match_operand:GPR 3 "immediate_operand")]))
10728    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10729   ""
10731   bool invert = false;
10733   enum rtx_code cond_code = GET_CODE (operands[1]);
10735   rtx op0 = operands[0];
10736   rtx op1 = operands[2];
10737   HOST_WIDE_INT val = INTVAL (operands[3]);
10739   if (cond_code == GEU || cond_code == GTU)
10740     {
10741       cond_code = reverse_condition (cond_code);
10742       invert = true;
10743     }
10745   if (cond_code == LEU)
10746     val++;
10748   rtx tmp = gen_reg_rtx (<MODE>mode);
10749   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10750   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10751   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10752   rtx x = gen_reg_rtx (<MODE>mode);
10753   if (val < 0)
10754     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10755   else
10756     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10758   if (invert)
10759     {
10760       rtx tmp = gen_reg_rtx (<MODE>mode);
10761       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10762       x = tmp;
10763     }
10765   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10766   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10768   DONE;
10771 (define_expand "cstore<mode>4"
10772   [(use (match_operator 1 "rs6000_cbranch_operator"
10773          [(match_operand:GPR 2 "gpc_reg_operand")
10774           (match_operand:GPR 3 "reg_or_short_operand")]))
10775    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10776   ""
10778   /* Use ISEL if the user asked for it.  */
10779   if (TARGET_ISEL)
10780     rs6000_emit_sISEL (<MODE>mode, operands);
10782   /* Expanding EQ and NE directly to some machine instructions does not help
10783      but does hurt combine.  So don't.  */
10784   else if (GET_CODE (operands[1]) == EQ)
10785     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10786   else if (<MODE>mode == Pmode
10787            && GET_CODE (operands[1]) == NE)
10788     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10789   else if (GET_CODE (operands[1]) == NE)
10790     {
10791       rtx tmp = gen_reg_rtx (<MODE>mode);
10792       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10793       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10794     }
10796   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10797      etc. combinations magically work out just right.  */
10798   else if (<MODE>mode == Pmode
10799            && unsigned_comparison_operator (operands[1], VOIDmode))
10800     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10801                                            operands[2], operands[3]));
10803   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
10804   else if (<MODE>mode == SImode && Pmode == DImode)
10805     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
10806                                     operands[2], operands[3]));
10808   /* For signed comparisons against a constant, we can do some simple
10809      bit-twiddling.  */
10810   else if (signed_comparison_operator (operands[1], VOIDmode)
10811            && CONST_INT_P (operands[3]))
10812     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10813                                              operands[2], operands[3]));
10815   /* And similarly for unsigned comparisons.  */
10816   else if (unsigned_comparison_operator (operands[1], VOIDmode)
10817            && CONST_INT_P (operands[3]))
10818     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10819                                                operands[2], operands[3]));
10821   /* We also do not want to use mfcr for signed comparisons.  */
10822   else if (<MODE>mode == Pmode
10823            && signed_comparison_operator (operands[1], VOIDmode))
10824     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
10825                                          operands[2], operands[3]));
10827   /* Everything else, use the mfcr brute force.  */
10828   else
10829     rs6000_emit_sCOND (<MODE>mode, operands);
10831   DONE;
10834 (define_expand "cstore<mode>4"
10835   [(use (match_operator 1 "rs6000_cbranch_operator"
10836          [(match_operand:FP 2 "gpc_reg_operand")
10837           (match_operand:FP 3 "gpc_reg_operand")]))
10838    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10839   ""
10841   rs6000_emit_sCOND (<MODE>mode, operands);
10842   DONE;
10846 (define_expand "stack_protect_set"
10847   [(match_operand 0 "memory_operand" "")
10848    (match_operand 1 "memory_operand" "")]
10849   ""
10851 #ifdef TARGET_THREAD_SSP_OFFSET
10852   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10853   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10854   operands[1] = gen_rtx_MEM (Pmode, addr);
10855 #endif
10856   if (TARGET_64BIT)
10857     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10858   else
10859     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10860   DONE;
10863 (define_insn "stack_protect_setsi"
10864   [(set (match_operand:SI 0 "memory_operand" "=m")
10865         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10866    (set (match_scratch:SI 2 "=&r") (const_int 0))]
10867   "TARGET_32BIT"
10868   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10869   [(set_attr "type" "three")
10870    (set_attr "length" "12")])
10872 (define_insn "stack_protect_setdi"
10873   [(set (match_operand:DI 0 "memory_operand" "=Y")
10874         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10875    (set (match_scratch:DI 2 "=&r") (const_int 0))]
10876   "TARGET_64BIT"
10877   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10878   [(set_attr "type" "three")
10879    (set_attr "length" "12")])
10881 (define_expand "stack_protect_test"
10882   [(match_operand 0 "memory_operand" "")
10883    (match_operand 1 "memory_operand" "")
10884    (match_operand 2 "" "")]
10885   ""
10887   rtx test, op0, op1;
10888 #ifdef TARGET_THREAD_SSP_OFFSET
10889   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10890   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10891   operands[1] = gen_rtx_MEM (Pmode, addr);
10892 #endif
10893   op0 = operands[0];
10894   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10895   test = gen_rtx_EQ (VOIDmode, op0, op1);
10896   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10897   DONE;
10900 (define_insn "stack_protect_testsi"
10901   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10902         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10903                       (match_operand:SI 2 "memory_operand" "m,m")]
10904                      UNSPEC_SP_TEST))
10905    (set (match_scratch:SI 4 "=r,r") (const_int 0))
10906    (clobber (match_scratch:SI 3 "=&r,&r"))]
10907   "TARGET_32BIT"
10908   "@
10909    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10910    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10911   [(set_attr "length" "16,20")])
10913 (define_insn "stack_protect_testdi"
10914   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10915         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10916                       (match_operand:DI 2 "memory_operand" "Y,Y")]
10917                      UNSPEC_SP_TEST))
10918    (set (match_scratch:DI 4 "=r,r") (const_int 0))
10919    (clobber (match_scratch:DI 3 "=&r,&r"))]
10920   "TARGET_64BIT"
10921   "@
10922    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10923    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10924   [(set_attr "length" "16,20")])
10927 ;; Here are the actual compare insns.
10928 (define_insn "*cmp<mode>_signed"
10929   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10930         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10931                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10932   ""
10933   "cmp<wd>%I2 %0,%1,%2"
10934   [(set_attr "type" "cmp")])
10936 (define_insn "*cmp<mode>_unsigned"
10937   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10938         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
10939                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
10940   ""
10941   "cmpl<wd>%I2 %0,%1,%2"
10942   [(set_attr "type" "cmp")])
10944 ;; If we are comparing a register for equality with a large constant,
10945 ;; we can do this with an XOR followed by a compare.  But this is profitable
10946 ;; only if the large constant is only used for the comparison (and in this
10947 ;; case we already have a register to reuse as scratch).
10949 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10950 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10952 (define_peephole2
10953   [(set (match_operand:SI 0 "register_operand")
10954         (match_operand:SI 1 "logical_const_operand" ""))
10955    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10956                        [(match_dup 0)
10957                         (match_operand:SI 2 "logical_const_operand" "")]))
10958    (set (match_operand:CC 4 "cc_reg_operand" "")
10959         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10960                     (match_dup 0)))
10961    (set (pc)
10962         (if_then_else (match_operator 6 "equality_operator"
10963                        [(match_dup 4) (const_int 0)])
10964                       (match_operand 7 "" "")
10965                       (match_operand 8 "" "")))]
10966   "peep2_reg_dead_p (3, operands[0])
10967    && peep2_reg_dead_p (4, operands[4])
10968    && REGNO (operands[0]) != REGNO (operands[5])"
10969  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10970   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10971   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10974   /* Get the constant we are comparing against, and see what it looks like
10975      when sign-extended from 16 to 32 bits.  Then see what constant we could
10976      XOR with SEXTC to get the sign-extended value.  */
10977   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10978                                               SImode,
10979                                               operands[1], operands[2]);
10980   HOST_WIDE_INT c = INTVAL (cnst);
10981   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10982   HOST_WIDE_INT xorv = c ^ sextc;
10984   operands[9] = GEN_INT (xorv);
10985   operands[10] = GEN_INT (sextc);
10988 ;; The following two insns don't exist as single insns, but if we provide
10989 ;; them, we can swap an add and compare, which will enable us to overlap more
10990 ;; of the required delay between a compare and branch.  We generate code for
10991 ;; them by splitting.
10993 (define_insn ""
10994   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10995         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10996                     (match_operand:SI 2 "short_cint_operand" "i")))
10997    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10998         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10999   ""
11000   "#"
11001   [(set_attr "length" "8")])
11003 (define_insn ""
11004   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11005         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11006                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11007    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11008         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11009   ""
11010   "#"
11011   [(set_attr "length" "8")])
11013 (define_split
11014   [(set (match_operand:CC 3 "cc_reg_operand" "")
11015         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11016                     (match_operand:SI 2 "short_cint_operand" "")))
11017    (set (match_operand:SI 0 "gpc_reg_operand" "")
11018         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11019   ""
11020   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11021    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11023 (define_split
11024   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11025         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11026                        (match_operand:SI 2 "u_short_cint_operand" "")))
11027    (set (match_operand:SI 0 "gpc_reg_operand" "")
11028         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11029   ""
11030   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11031    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11033 ;; Only need to compare second words if first words equal
11034 (define_insn "*cmp<mode>_internal1"
11035   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11036         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11037                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11038   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11039    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11040   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11041   [(set_attr "type" "fpcompare")
11042    (set_attr "length" "12")])
11044 (define_insn_and_split "*cmp<mode>_internal2"
11045   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11046         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11047                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11048     (clobber (match_scratch:DF 3 "=d"))
11049     (clobber (match_scratch:DF 4 "=d"))
11050     (clobber (match_scratch:DF 5 "=d"))
11051     (clobber (match_scratch:DF 6 "=d"))
11052     (clobber (match_scratch:DF 7 "=d"))
11053     (clobber (match_scratch:DF 8 "=d"))
11054     (clobber (match_scratch:DF 9 "=d"))
11055     (clobber (match_scratch:DF 10 "=d"))
11056     (clobber (match_scratch:GPR 11 "=b"))]
11057   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11058    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11059   "#"
11060   "&& reload_completed"
11061   [(set (match_dup 3) (match_dup 14))
11062    (set (match_dup 4) (match_dup 15))
11063    (set (match_dup 9) (abs:DF (match_dup 5)))
11064    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11065    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11066                            (label_ref (match_dup 12))
11067                            (pc)))
11068    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11069    (set (pc) (label_ref (match_dup 13)))
11070    (match_dup 12)
11071    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11072    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11073    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11074    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11075    (match_dup 13)]
11077   REAL_VALUE_TYPE rv;
11078   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11079   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11081   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11082   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11083   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11084   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11085   operands[12] = gen_label_rtx ();
11086   operands[13] = gen_label_rtx ();
11087   real_inf (&rv);
11088   operands[14] = force_const_mem (DFmode,
11089                                   const_double_from_real_value (rv, DFmode));
11090   operands[15] = force_const_mem (DFmode,
11091                                   const_double_from_real_value (dconst0,
11092                                                                 DFmode));
11093   if (TARGET_TOC)
11094     {
11095       rtx tocref;
11096       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11097       operands[14] = gen_const_mem (DFmode, tocref);
11098       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11099       operands[15] = gen_const_mem (DFmode, tocref);
11100       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11101       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11102     }
11105 ;; Now we have the scc insns.  We can do some combinations because of the
11106 ;; way the machine works.
11108 ;; Note that this is probably faster if we can put an insn between the
11109 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11110 ;; cases the insns below which don't use an intermediate CR field will
11111 ;; be used instead.
11112 (define_insn ""
11113   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11114         (match_operator:SI 1 "scc_comparison_operator"
11115                            [(match_operand 2 "cc_reg_operand" "y")
11116                             (const_int 0)]))]
11117   ""
11118   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11119   [(set (attr "type")
11120      (cond [(match_test "TARGET_MFCRF")
11121                 (const_string "mfcrf")
11122            ]
11123         (const_string "mfcr")))
11124    (set_attr "length" "8")])
11126 ;; Same as above, but get the GT bit.
11127 (define_insn "move_from_CR_gt_bit"
11128   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11129         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11130   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11131   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11132   [(set_attr "type" "mfcr")
11133    (set_attr "length" "8")])
11135 ;; Same as above, but get the OV/ORDERED bit.
11136 (define_insn "move_from_CR_ov_bit"
11137   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11138         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11139                    UNSPEC_MV_CR_OV))]
11140   "TARGET_ISEL"
11141   "mfcr %0\;rlwinm %0,%0,%t1,1"
11142   [(set_attr "type" "mfcr")
11143    (set_attr "length" "8")])
11145 (define_insn ""
11146   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11147         (match_operator:DI 1 "scc_comparison_operator"
11148                            [(match_operand 2 "cc_reg_operand" "y")
11149                             (const_int 0)]))]
11150   "TARGET_POWERPC64"
11151   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11152   [(set (attr "type")
11153      (cond [(match_test "TARGET_MFCRF")
11154                 (const_string "mfcrf")
11155            ]
11156         (const_string "mfcr")))
11157    (set_attr "length" "8")])
11159 (define_insn ""
11160   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11161         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11162                                        [(match_operand 2 "cc_reg_operand" "y,y")
11163                                         (const_int 0)])
11164                     (const_int 0)))
11165    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11166         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11167   "TARGET_32BIT"
11168   "@
11169    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11170    #"
11171   [(set_attr "type" "shift")
11172    (set_attr "dot" "yes")
11173    (set_attr "length" "8,16")])
11175 (define_split
11176   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11177         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11178                                        [(match_operand 2 "cc_reg_operand" "")
11179                                         (const_int 0)])
11180                     (const_int 0)))
11181    (set (match_operand:SI 3 "gpc_reg_operand" "")
11182         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11183   "TARGET_32BIT && reload_completed"
11184   [(set (match_dup 3)
11185         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11186    (set (match_dup 0)
11187         (compare:CC (match_dup 3)
11188                     (const_int 0)))]
11189   "")
11191 (define_insn ""
11192   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11193         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11194                                       [(match_operand 2 "cc_reg_operand" "y")
11195                                        (const_int 0)])
11196                    (match_operand:SI 3 "const_int_operand" "n")))]
11197   ""
11198   "*
11200   int is_bit = ccr_bit (operands[1], 1);
11201   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11202   int count;
11204   if (is_bit >= put_bit)
11205     count = is_bit - put_bit;
11206   else
11207     count = 32 - (put_bit - is_bit);
11209   operands[4] = GEN_INT (count);
11210   operands[5] = GEN_INT (put_bit);
11212   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11214   [(set (attr "type")
11215      (cond [(match_test "TARGET_MFCRF")
11216                 (const_string "mfcrf")
11217            ]
11218         (const_string "mfcr")))
11219    (set_attr "length" "8")])
11221 (define_insn ""
11222   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11223         (compare:CC
11224          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11225                                        [(match_operand 2 "cc_reg_operand" "y,y")
11226                                         (const_int 0)])
11227                     (match_operand:SI 3 "const_int_operand" "n,n"))
11228          (const_int 0)))
11229    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11230         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11231                    (match_dup 3)))]
11232   ""
11233   "*
11235   int is_bit = ccr_bit (operands[1], 1);
11236   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11237   int count;
11239   /* Force split for non-cc0 compare.  */
11240   if (which_alternative == 1)
11241      return \"#\";
11243   if (is_bit >= put_bit)
11244     count = is_bit - put_bit;
11245   else
11246     count = 32 - (put_bit - is_bit);
11248   operands[5] = GEN_INT (count);
11249   operands[6] = GEN_INT (put_bit);
11251   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11253   [(set_attr "type" "shift")
11254    (set_attr "dot" "yes")
11255    (set_attr "length" "8,16")])
11257 (define_split
11258   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11259         (compare:CC
11260          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11261                                        [(match_operand 2 "cc_reg_operand" "")
11262                                         (const_int 0)])
11263                     (match_operand:SI 3 "const_int_operand" ""))
11264          (const_int 0)))
11265    (set (match_operand:SI 4 "gpc_reg_operand" "")
11266         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11267                    (match_dup 3)))]
11268   "reload_completed"
11269   [(set (match_dup 4)
11270         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11271                    (match_dup 3)))
11272    (set (match_dup 0)
11273         (compare:CC (match_dup 4)
11274                     (const_int 0)))]
11275   "")
11277 ;; There is a 3 cycle delay between consecutive mfcr instructions
11278 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11280 (define_peephole
11281   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11282         (match_operator:SI 1 "scc_comparison_operator"
11283                            [(match_operand 2 "cc_reg_operand" "y")
11284                             (const_int 0)]))
11285    (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11286         (match_operator:SI 4 "scc_comparison_operator"
11287                            [(match_operand 5 "cc_reg_operand" "y")
11288                             (const_int 0)]))]
11289   "REGNO (operands[2]) != REGNO (operands[5])"
11290   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11291   [(set_attr "type" "mfcr")
11292    (set_attr "length" "12")])
11294 (define_peephole
11295   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11296         (match_operator:DI 1 "scc_comparison_operator"
11297                            [(match_operand 2 "cc_reg_operand" "y")
11298                             (const_int 0)]))
11299    (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11300         (match_operator:DI 4 "scc_comparison_operator"
11301                            [(match_operand 5 "cc_reg_operand" "y")
11302                             (const_int 0)]))]
11303   "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11304   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11305   [(set_attr "type" "mfcr")
11306    (set_attr "length" "12")])
11309 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11310                               (DI "rKJI")])
11312 (define_insn_and_split "eq<mode>3"
11313   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11314         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11315                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11316    (clobber (match_scratch:GPR 3 "=r"))
11317    (clobber (match_scratch:GPR 4 "=r"))]
11318   ""
11319   "#"
11320   ""
11321   [(set (match_dup 4)
11322         (clz:GPR (match_dup 3)))
11323    (set (match_dup 0)
11324         (lshiftrt:GPR (match_dup 4)
11325                       (match_dup 5)))]
11327   operands[3] = rs6000_emit_eqne (<MODE>mode,
11328                                   operands[1], operands[2], operands[3]);
11330   if (GET_CODE (operands[4]) == SCRATCH)
11331     operands[4] = gen_reg_rtx (<MODE>mode);
11333   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11335   [(set (attr "length")
11336         (if_then_else (match_test "operands[2] == const0_rtx")
11337                       (const_string "8")
11338                       (const_string "12")))])
11340 (define_insn_and_split "ne<mode>3"
11341   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11342         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11343               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11344    (clobber (match_scratch:P 3 "=r"))
11345    (clobber (match_scratch:P 4 "=r"))
11346    (clobber (reg:P CA_REGNO))]
11347   "!TARGET_ISEL"
11348   "#"
11349   ""
11350   [(parallel [(set (match_dup 4)
11351                    (plus:P (match_dup 3)
11352                            (const_int -1)))
11353               (set (reg:P CA_REGNO)
11354                    (ne:P (match_dup 3)
11355                          (const_int 0)))])
11356    (parallel [(set (match_dup 0)
11357                    (plus:P (plus:P (not:P (match_dup 4))
11358                                    (reg:P CA_REGNO))
11359                            (match_dup 3)))
11360               (clobber (reg:P CA_REGNO))])]
11362   operands[3] = rs6000_emit_eqne (<MODE>mode,
11363                                   operands[1], operands[2], operands[3]);
11365   if (GET_CODE (operands[4]) == SCRATCH)
11366     operands[4] = gen_reg_rtx (<MODE>mode);
11368   [(set (attr "length")
11369         (if_then_else (match_test "operands[2] == const0_rtx")
11370                       (const_string "8")
11371                       (const_string "12")))])
11373 (define_insn_and_split "*neg_eq_<mode>"
11374   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11375         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11376                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11377    (clobber (match_scratch:P 3 "=r"))
11378    (clobber (match_scratch:P 4 "=r"))
11379    (clobber (reg:P CA_REGNO))]
11380   ""
11381   "#"
11382   ""
11383   [(parallel [(set (match_dup 4)
11384                    (plus:P (match_dup 3)
11385                            (const_int -1)))
11386               (set (reg:P CA_REGNO)
11387                    (ne:P (match_dup 3)
11388                          (const_int 0)))])
11389    (parallel [(set (match_dup 0)
11390                    (plus:P (reg:P CA_REGNO)
11391                            (const_int -1)))
11392               (clobber (reg:P CA_REGNO))])]
11394   operands[3] = rs6000_emit_eqne (<MODE>mode,
11395                                   operands[1], operands[2], operands[3]);
11397   if (GET_CODE (operands[4]) == SCRATCH)
11398     operands[4] = gen_reg_rtx (<MODE>mode);
11400   [(set (attr "length")
11401         (if_then_else (match_test "operands[2] == const0_rtx")
11402                       (const_string "8")
11403                       (const_string "12")))])
11405 (define_insn_and_split "*neg_ne_<mode>"
11406   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11407         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11408                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11409    (clobber (match_scratch:P 3 "=r"))
11410    (clobber (match_scratch:P 4 "=r"))
11411    (clobber (reg:P CA_REGNO))]
11412   ""
11413   "#"
11414   ""
11415   [(parallel [(set (match_dup 4)
11416                    (neg:P (match_dup 3)))
11417               (set (reg:P CA_REGNO)
11418                    (eq:P (match_dup 3)
11419                          (const_int 0)))])
11420    (parallel [(set (match_dup 0)
11421                    (plus:P (reg:P CA_REGNO)
11422                            (const_int -1)))
11423               (clobber (reg:P CA_REGNO))])]
11425   operands[3] = rs6000_emit_eqne (<MODE>mode,
11426                                   operands[1], operands[2], operands[3]);
11428   if (GET_CODE (operands[4]) == SCRATCH)
11429     operands[4] = gen_reg_rtx (<MODE>mode);
11431   [(set (attr "length")
11432         (if_then_else (match_test "operands[2] == const0_rtx")
11433                       (const_string "8")
11434                       (const_string "12")))])
11436 (define_insn_and_split "*plus_eq_<mode>"
11437   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11438         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11439                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11440                 (match_operand:P 3 "gpc_reg_operand" "r")))
11441    (clobber (match_scratch:P 4 "=r"))
11442    (clobber (match_scratch:P 5 "=r"))
11443    (clobber (reg:P CA_REGNO))]
11444   ""
11445   "#"
11446   ""
11447   [(parallel [(set (match_dup 5)
11448                    (neg:P (match_dup 4)))
11449               (set (reg:P CA_REGNO)
11450                    (eq:P (match_dup 4)
11451                          (const_int 0)))])
11452    (parallel [(set (match_dup 0)
11453                    (plus:P (match_dup 3)
11454                            (reg:P CA_REGNO)))
11455               (clobber (reg:P CA_REGNO))])]
11457   operands[4] = rs6000_emit_eqne (<MODE>mode,
11458                                   operands[1], operands[2], operands[4]);
11460   if (GET_CODE (operands[5]) == SCRATCH)
11461     operands[5] = gen_reg_rtx (<MODE>mode);
11463   [(set (attr "length")
11464         (if_then_else (match_test "operands[2] == const0_rtx")
11465                       (const_string "8")
11466                       (const_string "12")))])
11468 (define_insn_and_split "*plus_ne_<mode>"
11469   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11470         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11471                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11472                 (match_operand:P 3 "gpc_reg_operand" "r")))
11473    (clobber (match_scratch:P 4 "=r"))
11474    (clobber (match_scratch:P 5 "=r"))
11475    (clobber (reg:P CA_REGNO))]
11476   ""
11477   "#"
11478   ""
11479   [(parallel [(set (match_dup 5)
11480                    (plus:P (match_dup 4)
11481                            (const_int -1)))
11482               (set (reg:P CA_REGNO)
11483                    (ne:P (match_dup 4)
11484                          (const_int 0)))])
11485    (parallel [(set (match_dup 0)
11486                    (plus:P (match_dup 3)
11487                            (reg:P CA_REGNO)))
11488               (clobber (reg:P CA_REGNO))])]
11490   operands[4] = rs6000_emit_eqne (<MODE>mode,
11491                                   operands[1], operands[2], operands[4]);
11493   if (GET_CODE (operands[5]) == SCRATCH)
11494     operands[5] = gen_reg_rtx (<MODE>mode);
11496   [(set (attr "length")
11497         (if_then_else (match_test "operands[2] == const0_rtx")
11498                       (const_string "8")
11499                       (const_string "12")))])
11501 (define_insn_and_split "*minus_eq_<mode>"
11502   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11503         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11504                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11505                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11506    (clobber (match_scratch:P 4 "=r"))
11507    (clobber (match_scratch:P 5 "=r"))
11508    (clobber (reg:P CA_REGNO))]
11509   ""
11510   "#"
11511   ""
11512   [(parallel [(set (match_dup 5)
11513                    (plus:P (match_dup 4)
11514                            (const_int -1)))
11515               (set (reg:P CA_REGNO)
11516                    (ne:P (match_dup 4)
11517                          (const_int 0)))])
11518    (parallel [(set (match_dup 0)
11519                    (plus:P (plus:P (match_dup 3)
11520                                    (reg:P CA_REGNO))
11521                            (const_int -1)))
11522               (clobber (reg:P CA_REGNO))])]
11524   operands[4] = rs6000_emit_eqne (<MODE>mode,
11525                                   operands[1], operands[2], operands[4]);
11527   if (GET_CODE (operands[5]) == SCRATCH)
11528     operands[5] = gen_reg_rtx (<MODE>mode);
11530   [(set (attr "length")
11531         (if_then_else (match_test "operands[2] == const0_rtx")
11532                       (const_string "8")
11533                       (const_string "12")))])
11535 (define_insn_and_split "*minus_ne_<mode>"
11536   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11537         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11538                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11539                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11540    (clobber (match_scratch:P 4 "=r"))
11541    (clobber (match_scratch:P 5 "=r"))
11542    (clobber (reg:P CA_REGNO))]
11543   ""
11544   "#"
11545   ""
11546   [(parallel [(set (match_dup 5)
11547                    (neg:P (match_dup 4)))
11548               (set (reg:P CA_REGNO)
11549                    (eq:P (match_dup 4)
11550                          (const_int 0)))])
11551    (parallel [(set (match_dup 0)
11552                    (plus:P (plus:P (match_dup 3)
11553                                    (reg:P CA_REGNO))
11554                            (const_int -1)))
11555               (clobber (reg:P CA_REGNO))])]
11557   operands[4] = rs6000_emit_eqne (<MODE>mode,
11558                                   operands[1], operands[2], operands[4]);
11560   if (GET_CODE (operands[5]) == SCRATCH)
11561     operands[5] = gen_reg_rtx (<MODE>mode);
11563   [(set (attr "length")
11564         (if_then_else (match_test "operands[2] == const0_rtx")
11565                       (const_string "8")
11566                       (const_string "12")))])
11568 (define_insn_and_split "*eqsi3_ext<mode>"
11569   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11570         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11571                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11572    (clobber (match_scratch:SI 3 "=r"))
11573    (clobber (match_scratch:SI 4 "=r"))]
11574   ""
11575   "#"
11576   ""
11577   [(set (match_dup 4)
11578         (clz:SI (match_dup 3)))
11579    (set (match_dup 0)
11580         (zero_extend:EXTSI
11581           (lshiftrt:SI (match_dup 4)
11582                        (const_int 5))))]
11584   operands[3] = rs6000_emit_eqne (SImode,
11585                                   operands[1], operands[2], operands[3]);
11587   if (GET_CODE (operands[4]) == SCRATCH)
11588     operands[4] = gen_reg_rtx (SImode);
11590   [(set (attr "length")
11591         (if_then_else (match_test "operands[2] == const0_rtx")
11592                       (const_string "8")
11593                       (const_string "12")))])
11595 (define_insn_and_split "*nesi3_ext<mode>"
11596   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11597         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11598                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11599    (clobber (match_scratch:SI 3 "=r"))
11600    (clobber (match_scratch:SI 4 "=r"))
11601    (clobber (match_scratch:EXTSI 5 "=r"))]
11602   ""
11603   "#"
11604   ""
11605   [(set (match_dup 4)
11606         (clz:SI (match_dup 3)))
11607    (set (match_dup 5)
11608         (zero_extend:EXTSI
11609           (lshiftrt:SI (match_dup 4)
11610                        (const_int 5))))
11611    (set (match_dup 0)
11612         (xor:EXTSI (match_dup 5)
11613                    (const_int 1)))]
11615   operands[3] = rs6000_emit_eqne (SImode,
11616                                   operands[1], operands[2], operands[3]);
11618   if (GET_CODE (operands[4]) == SCRATCH)
11619     operands[4] = gen_reg_rtx (SImode);
11620   if (GET_CODE (operands[5]) == SCRATCH)
11621     operands[5] = gen_reg_rtx (<MODE>mode);
11623   [(set (attr "length")
11624         (if_then_else (match_test "operands[2] == const0_rtx")
11625                       (const_string "12")
11626                       (const_string "16")))])
11628 ;; Define both directions of branch and return.  If we need a reload
11629 ;; register, we'd rather use CR0 since it is much easier to copy a
11630 ;; register CC value to there.
11632 (define_insn ""
11633   [(set (pc)
11634         (if_then_else (match_operator 1 "branch_comparison_operator"
11635                                       [(match_operand 2
11636                                                       "cc_reg_operand" "y")
11637                                        (const_int 0)])
11638                       (label_ref (match_operand 0 "" ""))
11639                       (pc)))]
11640   ""
11641   "*
11643   return output_cbranch (operands[1], \"%l0\", 0, insn);
11645   [(set_attr "type" "branch")])
11647 (define_insn ""
11648   [(set (pc)
11649         (if_then_else (match_operator 0 "branch_comparison_operator"
11650                                       [(match_operand 1
11651                                                       "cc_reg_operand" "y")
11652                                        (const_int 0)])
11653                       (any_return)
11654                       (pc)))]
11655   "<return_pred>"
11656   "*
11658   return output_cbranch (operands[0], NULL, 0, insn);
11660   [(set_attr "type" "jmpreg")
11661    (set_attr "length" "4")])
11663 (define_insn ""
11664   [(set (pc)
11665         (if_then_else (match_operator 1 "branch_comparison_operator"
11666                                       [(match_operand 2
11667                                                       "cc_reg_operand" "y")
11668                                        (const_int 0)])
11669                       (pc)
11670                       (label_ref (match_operand 0 "" ""))))]
11671   ""
11672   "*
11674   return output_cbranch (operands[1], \"%l0\", 1, insn);
11676   [(set_attr "type" "branch")])
11678 (define_insn ""
11679   [(set (pc)
11680         (if_then_else (match_operator 0 "branch_comparison_operator"
11681                                       [(match_operand 1
11682                                                       "cc_reg_operand" "y")
11683                                        (const_int 0)])
11684                       (pc)
11685                       (any_return)))]
11686   "<return_pred>"
11687   "*
11689   return output_cbranch (operands[0], NULL, 1, insn);
11691   [(set_attr "type" "jmpreg")
11692    (set_attr "length" "4")])
11694 ;; Logic on condition register values.
11696 ; This pattern matches things like
11697 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11698 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
11699 ;                                  (const_int 1)))
11700 ; which are generated by the branch logic.
11701 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11703 (define_insn "*cceq_ior_compare"
11704   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11705         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11706                         [(match_operator:SI 2
11707                                       "branch_positive_comparison_operator"
11708                                       [(match_operand 3
11709                                                       "cc_reg_operand" "y,y")
11710                                        (const_int 0)])
11711                          (match_operator:SI 4
11712                                       "branch_positive_comparison_operator"
11713                                       [(match_operand 5
11714                                                       "cc_reg_operand" "0,y")
11715                                        (const_int 0)])])
11716                       (const_int 1)))]
11717   ""
11718   "cr%q1 %E0,%j2,%j4"
11719   [(set_attr "type" "cr_logical,delayed_cr")])
11721 ; Why is the constant -1 here, but 1 in the previous pattern?
11722 ; Because ~1 has all but the low bit set.
11723 (define_insn ""
11724   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11725         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11726                         [(not:SI (match_operator:SI 2
11727                                       "branch_positive_comparison_operator"
11728                                       [(match_operand 3
11729                                                       "cc_reg_operand" "y,y")
11730                                        (const_int 0)]))
11731                          (match_operator:SI 4
11732                                 "branch_positive_comparison_operator"
11733                                 [(match_operand 5
11734                                                 "cc_reg_operand" "0,y")
11735                                  (const_int 0)])])
11736                       (const_int -1)))]
11737   ""
11738   "cr%q1 %E0,%j2,%j4"
11739   [(set_attr "type" "cr_logical,delayed_cr")])
11741 (define_insn "*cceq_rev_compare"
11742   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11743         (compare:CCEQ (match_operator:SI 1
11744                                       "branch_positive_comparison_operator"
11745                                       [(match_operand 2
11746                                                       "cc_reg_operand" "0,y")
11747                                        (const_int 0)])
11748                       (const_int 0)))]
11749   ""
11750   "crnot %E0,%j1"
11751   [(set_attr "type" "cr_logical,delayed_cr")])
11753 ;; If we are comparing the result of two comparisons, this can be done
11754 ;; using creqv or crxor.
11756 (define_insn_and_split ""
11757   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11758         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11759                               [(match_operand 2 "cc_reg_operand" "y")
11760                                (const_int 0)])
11761                       (match_operator 3 "branch_comparison_operator"
11762                               [(match_operand 4 "cc_reg_operand" "y")
11763                                (const_int 0)])))]
11764   ""
11765   "#"
11766   ""
11767   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11768                                     (match_dup 5)))]
11769   "
11771   int positive_1, positive_2;
11773   positive_1 = branch_positive_comparison_operator (operands[1],
11774                                                     GET_MODE (operands[1]));
11775   positive_2 = branch_positive_comparison_operator (operands[3],
11776                                                     GET_MODE (operands[3]));
11778   if (! positive_1)
11779     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11780                                                             GET_CODE (operands[1])),
11781                                   SImode,
11782                                   operands[2], const0_rtx);
11783   else if (GET_MODE (operands[1]) != SImode)
11784     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11785                                   operands[2], const0_rtx);
11787   if (! positive_2)
11788     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11789                                                             GET_CODE (operands[3])),
11790                                   SImode,
11791                                   operands[4], const0_rtx);
11792   else if (GET_MODE (operands[3]) != SImode)
11793     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11794                                   operands[4], const0_rtx);
11796   if (positive_1 == positive_2)
11797     {
11798       operands[1] = gen_rtx_NOT (SImode, operands[1]);
11799       operands[5] = constm1_rtx;
11800     }
11801   else
11802     {
11803       operands[5] = const1_rtx;
11804     }
11807 ;; Unconditional branch and return.
11809 (define_insn "jump"
11810   [(set (pc)
11811         (label_ref (match_operand 0 "" "")))]
11812   ""
11813   "b %l0"
11814   [(set_attr "type" "branch")])
11816 (define_insn "<return_str>return"
11817   [(any_return)]
11818   "<return_pred>"
11819   "blr"
11820   [(set_attr "type" "jmpreg")])
11822 (define_expand "indirect_jump"
11823   [(set (pc) (match_operand 0 "register_operand" ""))])
11825 (define_insn "*indirect_jump<mode>"
11826   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11827   ""
11828   "@
11829    bctr
11830    blr"
11831   [(set_attr "type" "jmpreg")])
11833 ;; Table jump for switch statements:
11834 (define_expand "tablejump"
11835   [(use (match_operand 0 "" ""))
11836    (use (label_ref (match_operand 1 "" "")))]
11837   ""
11838   "
11840   if (TARGET_32BIT)
11841     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11842   else
11843     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11844   DONE;
11847 (define_expand "tablejumpsi"
11848   [(set (match_dup 3)
11849         (plus:SI (match_operand:SI 0 "" "")
11850                  (match_dup 2)))
11851    (parallel [(set (pc) (match_dup 3))
11852               (use (label_ref (match_operand 1 "" "")))])]
11853   "TARGET_32BIT"
11854   "
11855 { operands[0] = force_reg (SImode, operands[0]);
11856   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11857   operands[3] = gen_reg_rtx (SImode);
11860 (define_expand "tablejumpdi"
11861   [(set (match_dup 4)
11862         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11863    (set (match_dup 3)
11864         (plus:DI (match_dup 4)
11865                  (match_dup 2)))
11866    (parallel [(set (pc) (match_dup 3))
11867               (use (label_ref (match_operand 1 "" "")))])]
11868   "TARGET_64BIT"
11869   "
11870 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11871   operands[3] = gen_reg_rtx (DImode);
11872   operands[4] = gen_reg_rtx (DImode);
11875 (define_insn "*tablejump<mode>_internal1"
11876   [(set (pc)
11877         (match_operand:P 0 "register_operand" "c,*l"))
11878    (use (label_ref (match_operand 1 "" "")))]
11879   ""
11880   "@
11881    bctr
11882    blr"
11883   [(set_attr "type" "jmpreg")])
11885 (define_insn "nop"
11886   [(unspec [(const_int 0)] UNSPEC_NOP)]
11887   ""
11888   "nop")
11890 (define_insn "group_ending_nop"
11891   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11892   ""
11893   "*
11895   if (rs6000_cpu_attr == CPU_POWER6)
11896     return \"ori 1,1,0\";
11897   return \"ori 2,2,0\";
11900 ;; Define the subtract-one-and-jump insns, starting with the template
11901 ;; so loop.c knows what to generate.
11903 (define_expand "doloop_end"
11904   [(use (match_operand 0 "" ""))        ; loop pseudo
11905    (use (match_operand 1 "" ""))]       ; label
11906   ""
11907   "
11909   if (TARGET_64BIT)
11910     {
11911       if (GET_MODE (operands[0]) != DImode)
11912         FAIL;
11913       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11914     }
11915   else
11916     {
11917       if (GET_MODE (operands[0]) != SImode)
11918         FAIL;
11919       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11920     }
11921   DONE;
11924 (define_expand "ctr<mode>"
11925   [(parallel [(set (pc)
11926                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
11927                                      (const_int 1))
11928                                  (label_ref (match_operand 1 "" ""))
11929                                  (pc)))
11930               (set (match_dup 0)
11931                    (plus:P (match_dup 0)
11932                             (const_int -1)))
11933               (clobber (match_scratch:CC 2 ""))
11934               (clobber (match_scratch:P 3 ""))])]
11935   ""
11936   "")
11938 ;; We need to be able to do this for any operand, including MEM, or we
11939 ;; will cause reload to blow up since we don't allow output reloads on
11940 ;; JUMP_INSNs.
11941 ;; For the length attribute to be calculated correctly, the
11942 ;; label MUST be operand 0.
11944 (define_insn "*ctr<mode>_internal1"
11945   [(set (pc)
11946         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11947                           (const_int 1))
11948                       (label_ref (match_operand 0 "" ""))
11949                       (pc)))
11950    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
11951         (plus:P (match_dup 1)
11952                  (const_int -1)))
11953    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11954    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11955   ""
11956   "*
11958   if (which_alternative != 0)
11959     return \"#\";
11960   else if (get_attr_length (insn) == 4)
11961     return \"bdnz %l0\";
11962   else
11963     return \"bdz $+8\;b %l0\";
11965   [(set_attr "type" "branch")
11966    (set_attr "length" "*,16,20,20")])
11968 (define_insn "*ctr<mode>_internal2"
11969   [(set (pc)
11970         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11971                           (const_int 1))
11972                       (pc)
11973                       (label_ref (match_operand 0 "" ""))))
11974    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
11975         (plus:P (match_dup 1)
11976                  (const_int -1)))
11977    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11978    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11979   ""
11980   "*
11982   if (which_alternative != 0)
11983     return \"#\";
11984   else if (get_attr_length (insn) == 4)
11985     return \"bdz %l0\";
11986   else
11987     return \"bdnz $+8\;b %l0\";
11989   [(set_attr "type" "branch")
11990    (set_attr "length" "*,16,20,20")])
11992 ;; Similar but use EQ
11994 (define_insn "*ctr<mode>_internal5"
11995   [(set (pc)
11996         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11997                           (const_int 1))
11998                       (label_ref (match_operand 0 "" ""))
11999                       (pc)))
12000    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12001         (plus:P (match_dup 1)
12002                  (const_int -1)))
12003    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12004    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12005   ""
12006   "*
12008   if (which_alternative != 0)
12009     return \"#\";
12010   else if (get_attr_length (insn) == 4)
12011     return \"bdz %l0\";
12012   else
12013     return \"bdnz $+8\;b %l0\";
12015   [(set_attr "type" "branch")
12016    (set_attr "length" "*,16,20,20")])
12018 (define_insn "*ctr<mode>_internal6"
12019   [(set (pc)
12020         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12021                           (const_int 1))
12022                       (pc)
12023                       (label_ref (match_operand 0 "" ""))))
12024    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12025         (plus:P (match_dup 1)
12026                  (const_int -1)))
12027    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12028    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12029   ""
12030   "*
12032   if (which_alternative != 0)
12033     return \"#\";
12034   else if (get_attr_length (insn) == 4)
12035     return \"bdnz %l0\";
12036   else
12037     return \"bdz $+8\;b %l0\";
12039   [(set_attr "type" "branch")
12040    (set_attr "length" "*,16,20,20")])
12042 ;; Now the splitters if we could not allocate the CTR register
12044 (define_split
12045   [(set (pc)
12046         (if_then_else (match_operator 2 "comparison_operator"
12047                                       [(match_operand:P 1 "gpc_reg_operand" "")
12048                                        (const_int 1)])
12049                       (match_operand 5 "" "")
12050                       (match_operand 6 "" "")))
12051    (set (match_operand:P 0 "int_reg_operand" "")
12052         (plus:P (match_dup 1) (const_int -1)))
12053    (clobber (match_scratch:CC 3 ""))
12054    (clobber (match_scratch:P 4 ""))]
12055   "reload_completed"
12056   [(set (match_dup 3)
12057         (compare:CC (match_dup 1)
12058                     (const_int 1)))
12059    (set (match_dup 0)
12060         (plus:P (match_dup 1)
12061                 (const_int -1)))
12062    (set (pc) (if_then_else (match_dup 7)
12063                            (match_dup 5)
12064                            (match_dup 6)))]
12065   "
12066 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12067                                 operands[3], const0_rtx); }")
12069 (define_split
12070   [(set (pc)
12071         (if_then_else (match_operator 2 "comparison_operator"
12072                                       [(match_operand:P 1 "gpc_reg_operand" "")
12073                                        (const_int 1)])
12074                       (match_operand 5 "" "")
12075                       (match_operand 6 "" "")))
12076    (set (match_operand:P 0 "nonimmediate_operand" "")
12077         (plus:P (match_dup 1) (const_int -1)))
12078    (clobber (match_scratch:CC 3 ""))
12079    (clobber (match_scratch:P 4 ""))]
12080   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12081   [(set (match_dup 3)
12082         (compare:CC (match_dup 1)
12083                     (const_int 1)))
12084    (set (match_dup 4)
12085         (plus:P (match_dup 1)
12086                 (const_int -1)))
12087    (set (match_dup 0)
12088         (match_dup 4))
12089    (set (pc) (if_then_else (match_dup 7)
12090                            (match_dup 5)
12091                            (match_dup 6)))]
12092   "
12093 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12094                                 operands[3], const0_rtx); }")
12096 (define_insn "trap"
12097   [(trap_if (const_int 1) (const_int 0))]
12098   ""
12099   "trap"
12100   [(set_attr "type" "trap")])
12102 (define_expand "ctrap<mode>4"
12103   [(trap_if (match_operator 0 "ordered_comparison_operator"
12104                             [(match_operand:GPR 1 "register_operand")
12105                              (match_operand:GPR 2 "reg_or_short_operand")])
12106             (match_operand 3 "zero_constant" ""))]
12107   ""
12108   "")
12110 (define_insn ""
12111   [(trap_if (match_operator 0 "ordered_comparison_operator"
12112                             [(match_operand:GPR 1 "register_operand" "r")
12113                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12114             (const_int 0))]
12115   ""
12116   "t<wd>%V0%I2 %1,%2"
12117   [(set_attr "type" "trap")])
12119 ;; Insns related to generating the function prologue and epilogue.
12121 (define_expand "prologue"
12122   [(use (const_int 0))]
12123   ""
12125   rs6000_emit_prologue ();
12126   if (!TARGET_SCHED_PROLOG)
12127     emit_insn (gen_blockage ());
12128   DONE;
12131 (define_insn "*movesi_from_cr_one"
12132   [(match_parallel 0 "mfcr_operation"
12133                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12134                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12135                                      (match_operand 3 "immediate_operand" "n")]
12136                           UNSPEC_MOVESI_FROM_CR))])]
12137   "TARGET_MFCRF"
12138   "*
12140   int mask = 0;
12141   int i;
12142   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12143   {
12144     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12145     operands[4] = GEN_INT (mask);
12146     output_asm_insn (\"mfcr %1,%4\", operands);
12147   }
12148   return \"\";
12150   [(set_attr "type" "mfcrf")])
12152 (define_insn "movesi_from_cr"
12153   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12154         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12155                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12156                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12157                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12158                    UNSPEC_MOVESI_FROM_CR))]
12159   ""
12160   "mfcr %0"
12161   [(set_attr "type" "mfcr")])
12163 (define_insn "*crsave"
12164   [(match_parallel 0 "crsave_operation"
12165                    [(set (match_operand:SI 1 "memory_operand" "=m")
12166                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12167   ""
12168   "stw %2,%1"
12169   [(set_attr "type" "store")])
12171 (define_insn "*stmw"
12172   [(match_parallel 0 "stmw_operation"
12173                    [(set (match_operand:SI 1 "memory_operand" "=m")
12174                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12175   "TARGET_MULTIPLE"
12176   "stmw %2,%1"
12177   [(set_attr "type" "store")
12178    (set_attr "update" "yes")
12179    (set_attr "indexed" "yes")])
12181 ; The following comment applies to:
12182 ;     save_gpregs_*
12183 ;     save_fpregs_*
12184 ;     restore_gpregs*
12185 ;     return_and_restore_gpregs*
12186 ;     return_and_restore_fpregs*
12187 ;     return_and_restore_fpregs_aix*
12189 ; The out-of-line save / restore functions expects one input argument.
12190 ; Since those are not standard call_insn's, we must avoid using
12191 ; MATCH_OPERAND for that argument. That way the register rename
12192 ; optimization will not try to rename this register.
12193 ; Each pattern is repeated for each possible register number used in 
12194 ; various ABIs (r11, r1, and for some functions r12)
12196 (define_insn "*save_gpregs_<mode>_r11"
12197   [(match_parallel 0 "any_parallel_operand"
12198                    [(clobber (reg:P 65))
12199                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12200                     (use (reg:P 11))
12201                     (set (match_operand:P 2 "memory_operand" "=m")
12202                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12203   ""
12204   "bl %1"
12205   [(set_attr "type" "branch")
12206    (set_attr "length" "4")])
12208 (define_insn "*save_gpregs_<mode>_r12"
12209   [(match_parallel 0 "any_parallel_operand"
12210                    [(clobber (reg:P 65))
12211                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12212                     (use (reg:P 12))
12213                     (set (match_operand:P 2 "memory_operand" "=m")
12214                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12215   ""
12216   "bl %1"
12217   [(set_attr "type" "branch")
12218    (set_attr "length" "4")])
12220 (define_insn "*save_gpregs_<mode>_r1"
12221   [(match_parallel 0 "any_parallel_operand"
12222                    [(clobber (reg:P 65))
12223                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12224                     (use (reg:P 1))
12225                     (set (match_operand:P 2 "memory_operand" "=m")
12226                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12227   ""
12228   "bl %1"
12229   [(set_attr "type" "branch")
12230    (set_attr "length" "4")])
12232 (define_insn "*save_fpregs_<mode>_r11"
12233   [(match_parallel 0 "any_parallel_operand"
12234                    [(clobber (reg:P 65))
12235                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12236                     (use (reg:P 11))
12237                     (set (match_operand:DF 2 "memory_operand" "=m")
12238                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12239   ""
12240   "bl %1"
12241   [(set_attr "type" "branch")
12242    (set_attr "length" "4")])
12244 (define_insn "*save_fpregs_<mode>_r12"
12245   [(match_parallel 0 "any_parallel_operand"
12246                    [(clobber (reg:P 65))
12247                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12248                     (use (reg:P 12))
12249                     (set (match_operand:DF 2 "memory_operand" "=m")
12250                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12251   ""
12252   "bl %1"
12253   [(set_attr "type" "branch")
12254    (set_attr "length" "4")])
12256 (define_insn "*save_fpregs_<mode>_r1"
12257   [(match_parallel 0 "any_parallel_operand"
12258                    [(clobber (reg:P 65))
12259                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12260                     (use (reg:P 1))
12261                     (set (match_operand:DF 2 "memory_operand" "=m")
12262                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12263   ""
12264   "bl %1"
12265   [(set_attr "type" "branch")
12266    (set_attr "length" "4")])
12268 ; This is to explain that changes to the stack pointer should
12269 ; not be moved over loads from or stores to stack memory.
12270 (define_insn "stack_tie"
12271   [(match_parallel 0 "tie_operand"
12272                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12273   ""
12274   ""
12275   [(set_attr "length" "0")])
12277 (define_expand "epilogue"
12278   [(use (const_int 0))]
12279   ""
12281   if (!TARGET_SCHED_PROLOG)
12282     emit_insn (gen_blockage ());
12283   rs6000_emit_epilogue (FALSE);
12284   DONE;
12287 ; On some processors, doing the mtcrf one CC register at a time is
12288 ; faster (like on the 604e).  On others, doing them all at once is
12289 ; faster; for instance, on the 601 and 750.
12291 (define_expand "movsi_to_cr_one"
12292   [(set (match_operand:CC 0 "cc_reg_operand" "")
12293         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12294                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12295   ""
12296   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12298 (define_insn "*movsi_to_cr"
12299   [(match_parallel 0 "mtcrf_operation"
12300                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12301                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12302                                      (match_operand 3 "immediate_operand" "n")]
12303                                     UNSPEC_MOVESI_TO_CR))])]
12304  ""
12305  "*
12307   int mask = 0;
12308   int i;
12309   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12310     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12311   operands[4] = GEN_INT (mask);
12312   return \"mtcrf %4,%2\";
12314   [(set_attr "type" "mtcr")])
12316 (define_insn "*mtcrfsi"
12317   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12318         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12319                     (match_operand 2 "immediate_operand" "n")]
12320                    UNSPEC_MOVESI_TO_CR))]
12321   "GET_CODE (operands[0]) == REG
12322    && CR_REGNO_P (REGNO (operands[0]))
12323    && GET_CODE (operands[2]) == CONST_INT
12324    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12325   "mtcrf %R0,%1"
12326   [(set_attr "type" "mtcr")])
12328 ; The load-multiple instructions have similar properties.
12329 ; Note that "load_multiple" is a name known to the machine-independent
12330 ; code that actually corresponds to the PowerPC load-string.
12332 (define_insn "*lmw"
12333   [(match_parallel 0 "lmw_operation"
12334                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12335                          (match_operand:SI 2 "memory_operand" "m"))])]
12336   "TARGET_MULTIPLE"
12337   "lmw %1,%2"
12338   [(set_attr "type" "load")
12339    (set_attr "update" "yes")
12340    (set_attr "indexed" "yes")
12341    (set_attr "cell_micro" "always")])
12343 (define_insn "*return_internal_<mode>"
12344   [(simple_return)
12345    (use (match_operand:P 0 "register_operand" "lc"))]
12346   ""
12347   "b%T0"
12348   [(set_attr "type" "jmpreg")])
12350 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12351 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12353 ; The following comment applies to:
12354 ;     save_gpregs_*
12355 ;     save_fpregs_*
12356 ;     restore_gpregs*
12357 ;     return_and_restore_gpregs*
12358 ;     return_and_restore_fpregs*
12359 ;     return_and_restore_fpregs_aix*
12361 ; The out-of-line save / restore functions expects one input argument.
12362 ; Since those are not standard call_insn's, we must avoid using
12363 ; MATCH_OPERAND for that argument. That way the register rename
12364 ; optimization will not try to rename this register.
12365 ; Each pattern is repeated for each possible register number used in 
12366 ; various ABIs (r11, r1, and for some functions r12)
12368 (define_insn "*restore_gpregs_<mode>_r11"
12369  [(match_parallel 0 "any_parallel_operand"
12370                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12371                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12372                    (use (reg:P 11))
12373                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12374                         (match_operand:P 4 "memory_operand" "m"))])]
12375  ""
12376  "bl %2"
12377  [(set_attr "type" "branch")
12378   (set_attr "length" "4")])
12380 (define_insn "*restore_gpregs_<mode>_r12"
12381  [(match_parallel 0 "any_parallel_operand"
12382                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12383                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12384                    (use (reg:P 12))
12385                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12386                         (match_operand:P 4 "memory_operand" "m"))])]
12387  ""
12388  "bl %2"
12389  [(set_attr "type" "branch")
12390   (set_attr "length" "4")])
12392 (define_insn "*restore_gpregs_<mode>_r1"
12393  [(match_parallel 0 "any_parallel_operand"
12394                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12395                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12396                    (use (reg:P 1))
12397                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12398                         (match_operand:P 4 "memory_operand" "m"))])]
12399  ""
12400  "bl %2"
12401  [(set_attr "type" "branch")
12402   (set_attr "length" "4")])
12404 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12405  [(match_parallel 0 "any_parallel_operand"
12406                   [(return)
12407                    (clobber (match_operand:P 1 "register_operand" "=l"))
12408                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12409                    (use (reg:P 11))
12410                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12411                         (match_operand:P 4 "memory_operand" "m"))])]
12412  ""
12413  "b %2"
12414  [(set_attr "type" "branch")
12415   (set_attr "length" "4")])
12417 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12418  [(match_parallel 0 "any_parallel_operand"
12419                   [(return)
12420                    (clobber (match_operand:P 1 "register_operand" "=l"))
12421                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12422                    (use (reg:P 12))
12423                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12424                         (match_operand:P 4 "memory_operand" "m"))])]
12425  ""
12426  "b %2"
12427  [(set_attr "type" "branch")
12428   (set_attr "length" "4")])
12430 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12431  [(match_parallel 0 "any_parallel_operand"
12432                   [(return)
12433                    (clobber (match_operand:P 1 "register_operand" "=l"))
12434                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12435                    (use (reg:P 1))
12436                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12437                         (match_operand:P 4 "memory_operand" "m"))])]
12438  ""
12439  "b %2"
12440  [(set_attr "type" "branch")
12441   (set_attr "length" "4")])
12443 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12444  [(match_parallel 0 "any_parallel_operand"
12445                   [(return)
12446                    (clobber (match_operand:P 1 "register_operand" "=l"))
12447                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12448                    (use (reg:P 11))
12449                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12450                         (match_operand:DF 4 "memory_operand" "m"))])]
12451  ""
12452  "b %2"
12453  [(set_attr "type" "branch")
12454   (set_attr "length" "4")])
12456 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12457  [(match_parallel 0 "any_parallel_operand"
12458                   [(return)
12459                    (clobber (match_operand:P 1 "register_operand" "=l"))
12460                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12461                    (use (reg:P 12))
12462                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12463                         (match_operand:DF 4 "memory_operand" "m"))])]
12464  ""
12465  "b %2"
12466  [(set_attr "type" "branch")
12467   (set_attr "length" "4")])
12469 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12470  [(match_parallel 0 "any_parallel_operand"
12471                   [(return)
12472                    (clobber (match_operand:P 1 "register_operand" "=l"))
12473                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12474                    (use (reg:P 1))
12475                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12476                         (match_operand:DF 4 "memory_operand" "m"))])]
12477  ""
12478  "b %2"
12479  [(set_attr "type" "branch")
12480   (set_attr "length" "4")])
12482 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12483  [(match_parallel 0 "any_parallel_operand"
12484                   [(return)
12485                    (use (match_operand:P 1 "register_operand" "l"))
12486                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12487                    (use (reg:P 11))
12488                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12489                         (match_operand:DF 4 "memory_operand" "m"))])]
12490  ""
12491  "b %2"
12492  [(set_attr "type" "branch")
12493   (set_attr "length" "4")])
12495 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12496  [(match_parallel 0 "any_parallel_operand"
12497                   [(return)
12498                    (use (match_operand:P 1 "register_operand" "l"))
12499                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12500                    (use (reg:P 1))
12501                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12502                         (match_operand:DF 4 "memory_operand" "m"))])]
12503  ""
12504  "b %2"
12505  [(set_attr "type" "branch")
12506   (set_attr "length" "4")])
12508 ; This is used in compiling the unwind routines.
12509 (define_expand "eh_return"
12510   [(use (match_operand 0 "general_operand" ""))]
12511   ""
12512   "
12514   if (TARGET_32BIT)
12515     emit_insn (gen_eh_set_lr_si (operands[0]));
12516   else
12517     emit_insn (gen_eh_set_lr_di (operands[0]));
12518   DONE;
12521 ; We can't expand this before we know where the link register is stored.
12522 (define_insn "eh_set_lr_<mode>"
12523   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12524                     UNSPECV_EH_RR)
12525    (clobber (match_scratch:P 1 "=&b"))]
12526   ""
12527   "#")
12529 (define_split
12530   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12531    (clobber (match_scratch 1 ""))]
12532   "reload_completed"
12533   [(const_int 0)]
12534   "
12536   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12537   DONE;
12540 (define_insn "prefetch"
12541   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12542              (match_operand:SI 1 "const_int_operand" "n")
12543              (match_operand:SI 2 "const_int_operand" "n"))]
12544   ""
12545   "*
12547   if (GET_CODE (operands[0]) == REG)
12548     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12549   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12551   [(set_attr "type" "load")])
12553 ;; Handle -fsplit-stack.
12555 (define_expand "split_stack_prologue"
12556   [(const_int 0)]
12557   ""
12559   rs6000_expand_split_stack_prologue ();
12560   DONE;
12563 (define_expand "load_split_stack_limit"
12564   [(set (match_operand 0)
12565         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12566   ""
12568   emit_insn (gen_rtx_SET (operands[0],
12569                           gen_rtx_UNSPEC (Pmode,
12570                                           gen_rtvec (1, const0_rtx),
12571                                           UNSPEC_STACK_CHECK)));
12572   DONE;
12575 (define_insn "load_split_stack_limit_di"
12576   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12577         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12578   "TARGET_64BIT"
12579   "ld %0,-0x7040(13)"
12580   [(set_attr "type" "load")
12581    (set_attr "update" "no")
12582    (set_attr "indexed" "no")])
12584 (define_insn "load_split_stack_limit_si"
12585   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12586         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12587   "!TARGET_64BIT"
12588   "lwz %0,-0x7020(2)"
12589   [(set_attr "type" "load")
12590    (set_attr "update" "no")
12591    (set_attr "indexed" "no")])
12593 ;; A return instruction which the middle-end doesn't see.
12594 (define_insn "split_stack_return"
12595   [(unspec_volatile [(const_int 0)] UNSPECV_SPLIT_STACK_RETURN)]
12596   ""
12597   "blr"
12598   [(set_attr "type" "jmpreg")])
12600 ;; If there are operand 0 bytes available on the stack, jump to
12601 ;; operand 1.
12602 (define_expand "split_stack_space_check"
12603   [(set (match_dup 2)
12604         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12605    (set (match_dup 3)
12606         (minus (reg STACK_POINTER_REGNUM)
12607                (match_operand 0)))
12608    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12609    (set (pc) (if_then_else
12610               (geu (match_dup 4) (const_int 0))
12611               (label_ref (match_operand 1))
12612               (pc)))]
12613   ""
12615   rs6000_split_stack_space_check (operands[0], operands[1]);
12616   DONE;
12619 (define_insn "bpermd_<mode>"
12620   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12621         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12622                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12623   "TARGET_POPCNTD"
12624   "bpermd %0,%1,%2"
12625   [(set_attr "type" "popcnt")])
12628 ;; Builtin fma support.  Handle 
12629 ;; Note that the conditions for expansion are in the FMA_F iterator.
12631 (define_expand "fma<mode>4"
12632   [(set (match_operand:FMA_F 0 "register_operand" "")
12633         (fma:FMA_F
12634           (match_operand:FMA_F 1 "register_operand" "")
12635           (match_operand:FMA_F 2 "register_operand" "")
12636           (match_operand:FMA_F 3 "register_operand" "")))]
12637   ""
12638   "")
12640 (define_insn "*fma<mode>4_fpr"
12641   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12642         (fma:SFDF
12643           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12644           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12645           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12646   "TARGET_<MODE>_FPR"
12647   "@
12648    fmadd<Ftrad> %0,%1,%2,%3
12649    xsmadda<Fvsx> %x0,%x1,%x2
12650    xsmaddm<Fvsx> %x0,%x1,%x3"
12651   [(set_attr "type" "fp")
12652    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12654 ; Altivec only has fma and nfms.
12655 (define_expand "fms<mode>4"
12656   [(set (match_operand:FMA_F 0 "register_operand" "")
12657         (fma:FMA_F
12658           (match_operand:FMA_F 1 "register_operand" "")
12659           (match_operand:FMA_F 2 "register_operand" "")
12660           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12661   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12662   "")
12664 (define_insn "*fms<mode>4_fpr"
12665   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12666         (fma:SFDF
12667          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12668          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12669          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12670   "TARGET_<MODE>_FPR"
12671   "@
12672    fmsub<Ftrad> %0,%1,%2,%3
12673    xsmsuba<Fvsx> %x0,%x1,%x2
12674    xsmsubm<Fvsx> %x0,%x1,%x3"
12675   [(set_attr "type" "fp")
12676    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12678 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12679 (define_expand "fnma<mode>4"
12680   [(set (match_operand:FMA_F 0 "register_operand" "")
12681         (neg:FMA_F
12682           (fma:FMA_F
12683             (match_operand:FMA_F 1 "register_operand" "")
12684             (match_operand:FMA_F 2 "register_operand" "")
12685             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12686   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12687   "")
12689 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12690 (define_expand "fnms<mode>4"
12691   [(set (match_operand:FMA_F 0 "register_operand" "")
12692         (neg:FMA_F
12693           (fma:FMA_F
12694             (match_operand:FMA_F 1 "register_operand" "")
12695             (match_operand:FMA_F 2 "register_operand" "")
12696             (match_operand:FMA_F 3 "register_operand" ""))))]
12697   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12698   "")
12700 ; Not an official optab name, but used from builtins.
12701 (define_expand "nfma<mode>4"
12702   [(set (match_operand:FMA_F 0 "register_operand" "")
12703         (neg:FMA_F
12704           (fma:FMA_F
12705             (match_operand:FMA_F 1 "register_operand" "")
12706             (match_operand:FMA_F 2 "register_operand" "")
12707             (match_operand:FMA_F 3 "register_operand" ""))))]
12708   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12709   "")
12711 (define_insn "*nfma<mode>4_fpr"
12712   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12713         (neg:SFDF
12714          (fma:SFDF
12715           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12716           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12717           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12718   "TARGET_<MODE>_FPR"
12719   "@
12720    fnmadd<Ftrad> %0,%1,%2,%3
12721    xsnmadda<Fvsx> %x0,%x1,%x2
12722    xsnmaddm<Fvsx> %x0,%x1,%x3"
12723   [(set_attr "type" "fp")
12724    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12726 ; Not an official optab name, but used from builtins.
12727 (define_expand "nfms<mode>4"
12728   [(set (match_operand:FMA_F 0 "register_operand" "")
12729         (neg:FMA_F
12730           (fma:FMA_F
12731             (match_operand:FMA_F 1 "register_operand" "")
12732             (match_operand:FMA_F 2 "register_operand" "")
12733             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12734   ""
12735   "")
12737 (define_insn "*nfmssf4_fpr"
12738   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12739         (neg:SFDF
12740          (fma:SFDF
12741           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12742           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12743           (neg:SFDF
12744            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
12745   "TARGET_<MODE>_FPR"
12746   "@
12747    fnmsub<Ftrad> %0,%1,%2,%3
12748    xsnmsuba<Fvsx> %x0,%x1,%x2
12749    xsnmsubm<Fvsx> %x0,%x1,%x3"
12750   [(set_attr "type" "fp")
12751    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12754 (define_expand "rs6000_get_timebase"
12755   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12756   ""
12758   if (TARGET_POWERPC64)
12759     emit_insn (gen_rs6000_mftb_di (operands[0]));
12760   else
12761     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12762   DONE;
12765 (define_insn "rs6000_get_timebase_ppc32"
12766   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12767         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12768    (clobber (match_scratch:SI 1 "=r"))
12769    (clobber (match_scratch:CC 2 "=y"))]
12770   "!TARGET_POWERPC64"
12772   if (WORDS_BIG_ENDIAN)
12773     if (TARGET_MFCRF)
12774       {
12775         return "mfspr %0,269\;"
12776                "mfspr %L0,268\;"
12777                "mfspr %1,269\;"
12778                "cmpw %2,%0,%1\;"
12779                "bne- %2,$-16";
12780       }
12781     else
12782       {
12783         return "mftbu %0\;"
12784                "mftb %L0\;"
12785                "mftbu %1\;"
12786                "cmpw %2,%0,%1\;"
12787                "bne- %2,$-16";
12788       }
12789   else
12790     if (TARGET_MFCRF)
12791       {
12792         return "mfspr %L0,269\;"
12793                "mfspr %0,268\;"
12794                "mfspr %1,269\;"
12795                "cmpw %2,%L0,%1\;"
12796                "bne- %2,$-16";
12797       }
12798     else
12799       {
12800         return "mftbu %L0\;"
12801                "mftb %0\;"
12802                "mftbu %1\;"
12803                "cmpw %2,%L0,%1\;"
12804                "bne- %2,$-16";
12805       }
12807   [(set_attr "length" "20")])
12809 (define_insn "rs6000_mftb_<mode>"
12810   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12811         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12812   ""
12814   if (TARGET_MFCRF)
12815     return "mfspr %0,268";
12816   else
12817     return "mftb %0";
12821 (define_insn "rs6000_mffs"
12822   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12823         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12824   "TARGET_HARD_FLOAT && TARGET_FPRS"
12825   "mffs %0")
12827 (define_insn "rs6000_mtfsf"
12828   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12829                      (match_operand:DF 1 "gpc_reg_operand" "d")]
12830                     UNSPECV_MTFSF)]
12831   "TARGET_HARD_FLOAT && TARGET_FPRS"
12832   "mtfsf %0,%1")
12835 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12836 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
12837 ;; register that is being loaded.  The fused ops must be physically adjacent.
12839 ;; There are two parts to addis fusion.  The support for fused TOCs occur
12840 ;; before register allocation, and is meant to reduce the lifetime for the
12841 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
12842 ;; to use the register that is being load.  The peephole2 then gathers any
12843 ;; other fused possibilities that it can find after register allocation.  If
12844 ;; power9 fusion is selected, we also fuse floating point loads/stores.
12846 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
12847 ;; before register allocation, so that we can avoid allocating a temporary base
12848 ;; register that won't be used, and that we try to load into base registers,
12849 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
12850 ;; (addis followed by load) even on power8.
12852 (define_split
12853   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
12854         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
12855   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
12856   [(parallel [(set (match_dup 0) (match_dup 2))
12857               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12858               (use (match_dup 3))
12859               (clobber (scratch:DI))])]
12861   operands[2] = fusion_wrap_memory_address (operands[1]);
12862   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
12865 (define_insn "*toc_fusionload_<mode>"
12866   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
12867         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
12868    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12869    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
12870    (clobber (match_scratch:DI 3 "=X,&b"))]
12871   "TARGET_TOC_FUSION_INT"
12873   if (base_reg_operand (operands[0], <MODE>mode))
12874     return emit_fusion_gpr_load (operands[0], operands[1]);
12876   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12878   [(set_attr "type" "load")
12879    (set_attr "length" "8")])
12881 (define_insn "*toc_fusionload_di"
12882   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
12883         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
12884    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12885    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
12886    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
12887   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
12888    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
12890   if (base_reg_operand (operands[0], DImode))
12891     return emit_fusion_gpr_load (operands[0], operands[1]);
12893   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12895   [(set_attr "type" "load")
12896    (set_attr "length" "8")])
12899 ;; Find cases where the addis that feeds into a load instruction is either used
12900 ;; once or is the same as the target register, and replace it with the fusion
12901 ;; insn
12903 (define_peephole2
12904   [(set (match_operand:P 0 "base_reg_operand" "")
12905         (match_operand:P 1 "fusion_gpr_addis" ""))
12906    (set (match_operand:INT1 2 "base_reg_operand" "")
12907         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12908   "TARGET_P8_FUSION
12909    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12910                          operands[3])"
12911   [(const_int 0)]
12913   expand_fusion_gpr_load (operands);
12914   DONE;
12917 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12918 ;; reload)
12920 (define_insn "fusion_gpr_load_<mode>"
12921   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
12922         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
12923                      UNSPEC_FUSION_GPR))]
12924   "TARGET_P8_FUSION"
12926   return emit_fusion_gpr_load (operands[0], operands[1]);
12928   [(set_attr "type" "load")
12929    (set_attr "length" "8")])
12932 ;; ISA 3.0 (power9) fusion support
12933 ;; Merge addis with floating load/store to FPRs (or GPRs).
12934 (define_peephole2
12935   [(set (match_operand:P 0 "base_reg_operand" "")
12936         (match_operand:P 1 "fusion_gpr_addis" ""))
12937    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
12938         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
12939   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12940    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12941   [(const_int 0)]
12943   expand_fusion_p9_load (operands);
12944   DONE;
12947 (define_peephole2
12948   [(set (match_operand:P 0 "base_reg_operand" "")
12949         (match_operand:P 1 "fusion_gpr_addis" ""))
12950    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
12951         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
12952   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12953    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12954   [(const_int 0)]
12956   expand_fusion_p9_store (operands);
12957   DONE;
12960 (define_peephole2
12961   [(set (match_operand:SDI 0 "int_reg_operand" "")
12962         (match_operand:SDI 1 "upper16_cint_operand" ""))
12963    (set (match_dup 0)
12964         (ior:SDI (match_dup 0)
12965                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
12966   "TARGET_P9_FUSION"
12967   [(set (match_dup 0)
12968         (unspec:SDI [(match_dup 1)
12969                      (match_dup 2)] UNSPEC_FUSION_P9))])
12971 (define_peephole2
12972   [(set (match_operand:SDI 0 "int_reg_operand" "")
12973         (match_operand:SDI 1 "upper16_cint_operand" ""))
12974    (set (match_operand:SDI 2 "int_reg_operand" "")
12975         (ior:SDI (match_dup 0)
12976                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
12977   "TARGET_P9_FUSION
12978    && !rtx_equal_p (operands[0], operands[2])
12979    && peep2_reg_dead_p (2, operands[0])"
12980   [(set (match_dup 2)
12981         (unspec:SDI [(match_dup 1)
12982                      (match_dup 3)] UNSPEC_FUSION_P9))])
12984 ;; Fusion insns, created by the define_peephole2 above (and eventually by
12985 ;; reload).  Because we want to eventually have secondary_reload generate
12986 ;; these, they have to have a single alternative that gives the register
12987 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
12988 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
12989   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
12990         (unspec:GPR_FUSION
12991          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12992          UNSPEC_FUSION_P9))
12993    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
12994   "TARGET_P9_FUSION"
12996   /* This insn is a secondary reload insn, which cannot have alternatives.
12997      If we are not loading up register 0, use the power8 fusion instead.  */
12998   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
12999     return emit_fusion_gpr_load (operands[0], operands[1]);
13001   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13003   [(set_attr "type" "load")
13004    (set_attr "length" "8")])
13006 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13007   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13008         (unspec:GPR_FUSION
13009          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13010          UNSPEC_FUSION_P9))
13011    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13012   "TARGET_P9_FUSION"
13014   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13016   [(set_attr "type" "store")
13017    (set_attr "length" "8")])
13019 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13020   [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13021         (unspec:FPR_FUSION
13022          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13023          UNSPEC_FUSION_P9))
13024    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13025   "TARGET_P9_FUSION"
13027   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13029   [(set_attr "type" "fpload")
13030    (set_attr "length" "8")])
13032 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13033   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13034         (unspec:FPR_FUSION
13035          [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13036          UNSPEC_FUSION_P9))
13037    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13038   "TARGET_P9_FUSION"
13040   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13042   [(set_attr "type" "fpstore")
13043    (set_attr "length" "8")])
13045 (define_insn "*fusion_p9_<mode>_constant"
13046   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13047         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13048                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13049                     UNSPEC_FUSION_P9))] 
13050   "TARGET_P9_FUSION"
13052   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13053   return "ori %0,%0,%2";
13055   [(set_attr "type" "two")
13056    (set_attr "length" "8")])
13059 ;; Miscellaneous ISA 2.06 (power7) instructions
13060 (define_insn "addg6s"
13061   [(set (match_operand:SI 0 "register_operand" "=r")
13062         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13063                     (match_operand:SI 2 "register_operand" "r")]
13064                    UNSPEC_ADDG6S))]
13065   "TARGET_POPCNTD"
13066   "addg6s %0,%1,%2"
13067   [(set_attr "type" "integer")
13068    (set_attr "length" "4")])
13070 (define_insn "cdtbcd"
13071   [(set (match_operand:SI 0 "register_operand" "=r")
13072         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13073                    UNSPEC_CDTBCD))]
13074   "TARGET_POPCNTD"
13075   "cdtbcd %0,%1"
13076   [(set_attr "type" "integer")
13077    (set_attr "length" "4")])
13079 (define_insn "cbcdtd"
13080   [(set (match_operand:SI 0 "register_operand" "=r")
13081         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13082                    UNSPEC_CBCDTD))]
13083   "TARGET_POPCNTD"
13084   "cbcdtd %0,%1"
13085   [(set_attr "type" "integer")
13086    (set_attr "length" "4")])
13088 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13089                                         UNSPEC_DIVEO
13090                                         UNSPEC_DIVEU
13091                                         UNSPEC_DIVEUO])
13093 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13094                              (UNSPEC_DIVEO      "eo")
13095                              (UNSPEC_DIVEU      "eu")
13096                              (UNSPEC_DIVEUO     "euo")])
13098 (define_insn "div<div_extend>_<mode>"
13099   [(set (match_operand:GPR 0 "register_operand" "=r")
13100         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13101                      (match_operand:GPR 2 "register_operand" "r")]
13102                     UNSPEC_DIV_EXTEND))]
13103   "TARGET_POPCNTD"
13104   "div<wd><div_extend> %0,%1,%2"
13105   [(set_attr "type" "div")
13106    (set_attr "size" "<bits>")])
13109 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13111 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13112 (define_mode_attr FP128_64 [(TF "DF")
13113                             (IF "DF")
13114                             (TD "DI")
13115                             (KF "DI")])
13117 (define_expand "unpack<mode>"
13118   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13119         (unspec:<FP128_64>
13120          [(match_operand:FMOVE128 1 "register_operand" "")
13121           (match_operand:QI 2 "const_0_to_1_operand" "")]
13122          UNSPEC_UNPACK_128BIT))]
13123   "FLOAT128_2REG_P (<MODE>mode)"
13124   "")
13126 (define_insn_and_split "unpack<mode>_dm"
13127   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13128         (unspec:<FP128_64>
13129          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13130           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13131          UNSPEC_UNPACK_128BIT))]
13132   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13133   "#"
13134   "&& reload_completed"
13135   [(set (match_dup 0) (match_dup 3))]
13137   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13139   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13140     {
13141       emit_note (NOTE_INSN_DELETED);
13142       DONE;
13143     }
13145   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13147   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13148    (set_attr "length" "4")])
13150 (define_insn_and_split "unpack<mode>_nodm"
13151   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13152         (unspec:<FP128_64>
13153          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13154           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13155          UNSPEC_UNPACK_128BIT))]
13156   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13157   "#"
13158   "&& reload_completed"
13159   [(set (match_dup 0) (match_dup 3))]
13161   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13163   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13164     {
13165       emit_note (NOTE_INSN_DELETED);
13166       DONE;
13167     }
13169   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13171   [(set_attr "type" "fp,fpstore")
13172    (set_attr "length" "4")])
13174 (define_insn_and_split "pack<mode>"
13175   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13176         (unspec:FMOVE128
13177          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13178           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13179          UNSPEC_PACK_128BIT))]
13180   "FLOAT128_2REG_P (<MODE>mode)"
13181   "@
13182    fmr %L0,%2
13183    #"
13184   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13185   [(set (match_dup 3) (match_dup 1))
13186    (set (match_dup 4) (match_dup 2))]
13188   unsigned dest_hi = REGNO (operands[0]);
13189   unsigned dest_lo = dest_hi + 1;
13191   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13192   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13194   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13195   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13197   [(set_attr "type" "fp,fp")
13198    (set_attr "length" "4,8")])
13200 (define_insn "unpack<mode>"
13201   [(set (match_operand:DI 0 "register_operand" "=d,d")
13202         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13203                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13204          UNSPEC_UNPACK_128BIT))]
13205   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13207   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13208     return ASM_COMMENT_START " xxpermdi to same register";
13210   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13211   return "xxpermdi %x0,%x1,%x1,%3";
13213   [(set_attr "type" "vecperm")])
13215 (define_insn "pack<mode>"
13216   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13217         (unspec:FMOVE128_VSX
13218          [(match_operand:DI 1 "register_operand" "d")
13219           (match_operand:DI 2 "register_operand" "d")]
13220          UNSPEC_PACK_128BIT))]
13221   "TARGET_VSX"
13222   "xxpermdi %x0,%x1,%x2,0"
13223   [(set_attr "type" "vecperm")])
13227 ;; ISA 2.08 IEEE 128-bit floating point support.
13229 (define_insn "add<mode>3"
13230   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13231         (plus:IEEE128
13232          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13233          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13234   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13235   "xsaddqp %0,%1,%2"
13236   [(set_attr "type" "vecfloat")])
13238 (define_insn "sub<mode>3"
13239   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13240         (minus:IEEE128
13241          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13242          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13243   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13244   "xssubqp %0,%1,%2"
13245   [(set_attr "type" "vecfloat")])
13247 (define_insn "mul<mode>3"
13248   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13249         (mult:IEEE128
13250          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13251          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13252   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13253   "xsmulqp %0,%1,%2"
13254   [(set_attr "type" "vecfloat")])
13256 (define_insn "div<mode>3"
13257   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13258         (div:IEEE128
13259          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13260          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13261   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13262   "xsdivqp %0,%1,%2"
13263   [(set_attr "type" "vecdiv")])
13265 (define_insn "sqrt<mode>2"
13266   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13267         (sqrt:IEEE128
13268          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13269   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13270    "xssqrtqp %0,%1"
13271   [(set_attr "type" "vecdiv")])
13273 (define_insn "copysign<mode>3"
13274   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13275         (unspec:IEEE128
13276          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13277           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13278          UNSPEC_COPYSIGN))]
13279   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13280    "xscpsgnqp %0,%2,%1"
13281   [(set_attr "type" "vecsimple")])
13283 (define_insn "neg<mode>2_hw"
13284   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13285         (neg:IEEE128
13286          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13287   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13288   "xsnegqp %0,%1"
13289   [(set_attr "type" "vecfloat")])
13292 (define_insn "abs<mode>2_hw"
13293   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13294         (abs:IEEE128
13295          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13296   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13297   "xsabsqp %0,%1"
13298   [(set_attr "type" "vecfloat")])
13301 (define_insn "*nabs<mode>2_hw"
13302   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13303         (neg:IEEE128
13304          (abs:IEEE128
13305           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13306   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13307   "xsnabsqp %0,%1"
13308   [(set_attr "type" "vecfloat")])
13310 ;; Initially don't worry about doing fusion
13311 (define_insn "*fma<mode>4_hw"
13312   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13313         (fma:IEEE128
13314          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13315          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13316          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13317   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13318   "xsmaddqp %0,%1,%2"
13319   [(set_attr "type" "vecfloat")])
13321 (define_insn "*fms<mode>4_hw"
13322   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13323         (fma:IEEE128
13324          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13325          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13326          (neg:IEEE128
13327           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13328   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13329   "xsmsubqp %0,%1,%2"
13330   [(set_attr "type" "vecfloat")])
13332 (define_insn "*nfma<mode>4_hw"
13333   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13334         (neg:IEEE128
13335          (fma:IEEE128
13336           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13337           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13338           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13339   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13340   "xsnmaddqp %0,%1,%2"
13341   [(set_attr "type" "vecfloat")])
13343 (define_insn "*nfms<mode>4_hw"
13344   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13345         (neg:IEEE128
13346          (fma:IEEE128
13347           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13348           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13349           (neg:IEEE128
13350            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13351   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13352   "xsnmsubqp %0,%1,%2"
13353   [(set_attr "type" "vecfloat")])
13355 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13356   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13357         (float_extend:IEEE128
13358          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13359   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13360   "xscvdpqp %0,%1"
13361   [(set_attr "type" "vecfloat")])
13363 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13364 ;; point is a simple copy.
13365 (define_insn_and_split "extendkftf2"
13366   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13367         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13368   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13369   "@
13370    #
13371    xxlor %x0,%x1,%x1"
13372   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13373   [(const_int 0)]
13375   emit_note (NOTE_INSN_DELETED);
13376   DONE;
13378   [(set_attr "type" "*,vecsimple")
13379    (set_attr "length" "0,4")])
13381 (define_insn_and_split "trunctfkf2"
13382   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13383         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13384   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13385   "@
13386    #
13387    xxlor %x0,%x1,%x1"
13388   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13389   [(const_int 0)]
13391   emit_note (NOTE_INSN_DELETED);
13392   DONE;
13394   [(set_attr "type" "*,vecsimple")
13395    (set_attr "length" "0,4")])
13397 (define_insn "trunc<mode>df2_hw"
13398   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13399         (float_truncate:DF
13400          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13401   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13402   "xscvqpdp %0,%1"
13403   [(set_attr "type" "vecfloat")])
13405 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13406 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13407 ;; conversion
13408 (define_insn_and_split "trunc<mode>sf2_hw"
13409   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13410         (float_truncate:SF
13411          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13412    (clobber (match_scratch:DF 2 "=v"))]
13413   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13414   "#"
13415   "&& 1"
13416   [(set (match_dup 2)
13417         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13418    (set (match_dup 0)
13419         (float_truncate:SF (match_dup 2)))]
13421   if (GET_CODE (operands[2]) == SCRATCH)
13422     operands[2] = gen_reg_rtx (DFmode);
13424   [(set_attr "type" "vecfloat")
13425    (set_attr "length" "8")])
13427 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13428 ;; allowed in the traditional floating point registers. Use V2DImode so that
13429 ;; we can get a value in an Altivec register.
13431 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13432   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13433         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13434    (clobber (match_scratch:V2DI 2 "=v,v"))]
13435   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13436   "#"
13437   "&& 1"
13438   [(pc)]
13440   convert_float128_to_int (operands, <CODE>);
13441   DONE;
13443   [(set_attr "length" "8")
13444    (set_attr "type" "mftgpr,fpstore")])
13446 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13447   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13448         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13449    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13450   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13451   "#"
13452   "&& 1"
13453   [(pc)]
13455   convert_float128_to_int (operands, <CODE>);
13456   DONE;
13458   [(set_attr "length" "8")
13459    (set_attr "type" "mftgpr,vecsimple,fpstore")])
13461 (define_insn_and_split "float<uns>_<mode>si2_hw"
13462   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13463         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13464    (clobber (match_scratch:V2DI 2 "=v,v"))]
13465   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13466   "#"
13467   "&& 1"
13468   [(pc)]
13470   convert_int_to_float128 (operands, <CODE>);
13471   DONE;
13473   [(set_attr "length" "8")
13474    (set_attr "type" "vecfloat")])
13476 (define_insn_and_split "float<uns>_<mode>di2_hw"
13477   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13478         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13479    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13480   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13481   "#"
13482   "&& 1"
13483   [(pc)]
13485   convert_int_to_float128 (operands, <CODE>);
13486   DONE;
13488   [(set_attr "length" "8")
13489    (set_attr "type" "vecfloat")])
13491 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13492 (define_insn "*xscvqp<su>wz_<mode>"
13493   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13494         (unspec:V2DI
13495          [(any_fix:SI
13496            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13497          UNSPEC_IEEE128_CONVERT))]
13498   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13499   "xscvqp<su>wz %0,%1"
13500   [(set_attr "type" "vecfloat")])
13502 (define_insn "*xscvqp<su>dz_<mode>"
13503   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13504         (unspec:V2DI
13505          [(any_fix:DI
13506            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13507          UNSPEC_IEEE128_CONVERT))]
13508   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13509   "xscvqp<su>dz %0,%1"
13510   [(set_attr "type" "vecfloat")])
13512 (define_insn "*xscv<su>dqp_<mode>"
13513   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13514         (any_float:IEEE128
13515          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13516                     UNSPEC_IEEE128_CONVERT)))]
13517   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13518   "xscv<su>dqp %0,%1"
13519   [(set_attr "type" "vecfloat")])
13521 (define_insn "*ieee128_mfvsrd_64bit"
13522   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13523         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13524                    UNSPEC_IEEE128_MOVE))]
13525   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13526   "@
13527    mfvsrd %0,%x1
13528    stxsdx %x1,%y0
13529    xxlor %x0,%x1,%x1"
13530   [(set_attr "type" "mftgpr,fpstore,vecsimple")])
13533 (define_insn "*ieee128_mfvsrd_32bit"
13534   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13535         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13536                    UNSPEC_IEEE128_MOVE))]
13537   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13538   "@
13539    stxsdx %x1,%y0
13540    xxlor %x0,%x1,%x1"
13541   [(set_attr "type" "fpstore,vecsimple")])
13543 (define_insn "*ieee128_mfvsrwz"
13544   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13545         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13546                    UNSPEC_IEEE128_MOVE))]
13547   "TARGET_FLOAT128_HW"
13548   "@
13549    mfvsrwz %0,%x1
13550    stxsiwx %x1,%y0"
13551   [(set_attr "type" "mftgpr,fpstore")])
13553 ;; 0 says do sign-extension, 1 says zero-extension
13554 (define_insn "*ieee128_mtvsrw"
13555   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13556         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13557                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13558                      UNSPEC_IEEE128_MOVE))]
13559   "TARGET_FLOAT128_HW"
13560   "@
13561    mtvsrwa %x0,%1
13562    lxsiwax %x0,%y1
13563    mtvsrwz %x0,%1
13564    lxsiwzx %x0,%y1"
13565   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13568 (define_insn "*ieee128_mtvsrd_64bit"
13569   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13570         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13571                      UNSPEC_IEEE128_MOVE))]
13572   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13573   "@
13574    mtvsrd %x0,%1
13575    lxsdx %x0,%y1
13576    xxlor %x0,%x1,%x1"
13577   [(set_attr "type" "mffgpr,fpload,vecsimple")])
13579 (define_insn "*ieee128_mtvsrd_32bit"
13580   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13581         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13582                      UNSPEC_IEEE128_MOVE))]
13583   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13584   "@
13585    lxsdx %x0,%y1
13586    xxlor %x0,%x1,%x1"
13587   [(set_attr "type" "fpload,vecsimple")])
13589 ;; IEEE 128-bit instructions with round to odd semantics
13590 (define_insn "*trunc<mode>df2_odd"
13591   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13592         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13593                    UNSPEC_ROUND_TO_ODD))]
13594   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13595   "xscvqpdpo %0,%1"
13596   [(set_attr "type" "vecfloat")])
13598 ;; IEEE 128-bit comparisons
13599 (define_insn "*cmp<mode>_hw"
13600   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13601         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13602                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13603   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13604    "xscmpuqp %0,%1,%2"
13605   [(set_attr "type" "fpcompare")])
13609 (include "sync.md")
13610 (include "vector.md")
13611 (include "vsx.md")
13612 (include "altivec.md")
13613 (include "spe.md")
13614 (include "dfp.md")
13615 (include "paired.md")
13616 (include "crypto.md")
13617 (include "htm.md")